~ubuntu-branches/debian/stretch/electrum/stretch

« back to all changes in this revision

Viewing changes to gui/kivy/tools/.buildozer/android/platform/python-for-android/dist/kivy/python-install/lib/python2.7/timeit.py

  • Committer: Package Import Robot
  • Author(s): Tristan Seligmann
  • Date: 2016-04-04 03:02:39 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20160404030239-0szgkio8yryjv7c9
Tags: 2.6.3-1
* New upstream release.
  - Drop backported install-wizard-connect.patch.
* Add Suggests: python-zbar and update the installation hint to suggest
  apt-get instead of pip (closes: #819517).
* Bump Standards-Version to 3.9.7 (no changes).
* Update Vcs-* links.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
 
 
3
"""Tool for measuring execution time of small code snippets.
 
4
 
 
5
This module avoids a number of common traps for measuring execution
 
6
times.  See also Tim Peters' introduction to the Algorithms chapter in
 
7
the Python Cookbook, published by O'Reilly.
 
8
 
 
9
Library usage: see the Timer class.
 
10
 
 
11
Command line usage:
 
12
    python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-h] [--] [statement]
 
13
 
 
14
Options:
 
15
  -n/--number N: how many times to execute 'statement' (default: see below)
 
16
  -r/--repeat N: how many times to repeat the timer (default 3)
 
17
  -s/--setup S: statement to be executed once initially (default 'pass')
 
18
  -t/--time: use time.time() (default on Unix)
 
19
  -c/--clock: use time.clock() (default on Windows)
 
20
  -v/--verbose: print raw timing results; repeat for more digits precision
 
21
  -h/--help: print this usage message and exit
 
22
  --: separate options from statement, use when statement starts with -
 
23
  statement: statement to be timed (default 'pass')
 
24
 
 
25
A multi-line statement may be given by specifying each line as a
 
26
separate argument; indented lines are possible by enclosing an
 
27
argument in quotes and using leading spaces.  Multiple -s options are
 
28
treated similarly.
 
29
 
 
30
If -n is not given, a suitable number of loops is calculated by trying
 
31
successive powers of 10 until the total time is at least 0.2 seconds.
 
32
 
 
33
The difference in default timer function is because on Windows,
 
34
clock() has microsecond granularity but time()'s granularity is 1/60th
 
35
of a second; on Unix, clock() has 1/100th of a second granularity and
 
36
time() is much more precise.  On either platform, the default timer
 
37
functions measure wall clock time, not the CPU time.  This means that
 
38
other processes running on the same computer may interfere with the
 
39
timing.  The best thing to do when accurate timing is necessary is to
 
40
repeat the timing a few times and use the best time.  The -r option is
 
41
good for this; the default of 3 repetitions is probably enough in most
 
42
cases.  On Unix, you can use clock() to measure CPU time.
 
43
 
 
44
Note: there is a certain baseline overhead associated with executing a
 
45
pass statement.  The code here doesn't try to hide it, but you should
 
46
be aware of it.  The baseline overhead can be measured by invoking the
 
47
program without arguments.
 
48
 
 
49
The baseline overhead differs between Python versions!  Also, to
 
50
fairly compare older Python versions to Python 2.3, you may want to
 
51
use python -O for the older versions to avoid timing SET_LINENO
 
52
instructions.
 
53
"""
 
54
 
 
55
import gc
 
56
import sys
 
57
import time
 
58
try:
 
59
    import itertools
 
60
except ImportError:
 
61
    # Must be an older Python version (see timeit() below)
 
62
    itertools = None
 
63
 
 
64
__all__ = ["Timer"]
 
65
 
 
66
dummy_src_name = "<timeit-src>"
 
67
default_number = 1000000
 
68
default_repeat = 3
 
69
 
 
70
if sys.platform == "win32":
 
71
    # On Windows, the best timer is time.clock()
 
72
    default_timer = time.clock
 
73
else:
 
74
    # On most other platforms the best timer is time.time()
 
75
    default_timer = time.time
 
76
 
 
77
# Don't change the indentation of the template; the reindent() calls
 
78
# in Timer.__init__() depend on setup being indented 4 spaces and stmt
 
79
# being indented 8 spaces.
 
80
template = """
 
81
def inner(_it, _timer):
 
82
    %(setup)s
 
83
    _t0 = _timer()
 
84
    for _i in _it:
 
85
        %(stmt)s
 
86
    _t1 = _timer()
 
87
    return _t1 - _t0
 
88
"""
 
89
 
 
90
def reindent(src, indent):
 
91
    """Helper to reindent a multi-line statement."""
 
92
    return src.replace("\n", "\n" + " "*indent)
 
93
 
 
94
def _template_func(setup, func):
 
95
    """Create a timer function. Used if the "statement" is a callable."""
 
96
    def inner(_it, _timer, _func=func):
 
97
        setup()
 
98
        _t0 = _timer()
 
99
        for _i in _it:
 
100
            _func()
 
101
        _t1 = _timer()
 
102
        return _t1 - _t0
 
103
    return inner
 
104
 
 
105
class Timer:
 
106
    """Class for timing execution speed of small code snippets.
 
107
 
 
108
    The constructor takes a statement to be timed, an additional
 
109
    statement used for setup, and a timer function.  Both statements
 
110
    default to 'pass'; the timer function is platform-dependent (see
 
111
    module doc string).
 
112
 
 
113
    To measure the execution time of the first statement, use the
 
114
    timeit() method.  The repeat() method is a convenience to call
 
115
    timeit() multiple times and return a list of results.
 
116
 
 
117
    The statements may contain newlines, as long as they don't contain
 
118
    multi-line string literals.
 
119
    """
 
120
 
 
121
    def __init__(self, stmt="pass", setup="pass", timer=default_timer):
 
122
        """Constructor.  See class doc string."""
 
123
        self.timer = timer
 
124
        ns = {}
 
125
        if isinstance(stmt, basestring):
 
126
            stmt = reindent(stmt, 8)
 
127
            if isinstance(setup, basestring):
 
128
                setup = reindent(setup, 4)
 
129
                src = template % {'stmt': stmt, 'setup': setup}
 
130
            elif hasattr(setup, '__call__'):
 
131
                src = template % {'stmt': stmt, 'setup': '_setup()'}
 
132
                ns['_setup'] = setup
 
133
            else:
 
134
                raise ValueError("setup is neither a string nor callable")
 
135
            self.src = src # Save for traceback display
 
136
            code = compile(src, dummy_src_name, "exec")
 
137
            exec code in globals(), ns
 
138
            self.inner = ns["inner"]
 
139
        elif hasattr(stmt, '__call__'):
 
140
            self.src = None
 
141
            if isinstance(setup, basestring):
 
142
                _setup = setup
 
143
                def setup():
 
144
                    exec _setup in globals(), ns
 
145
            elif not hasattr(setup, '__call__'):
 
146
                raise ValueError("setup is neither a string nor callable")
 
147
            self.inner = _template_func(setup, stmt)
 
148
        else:
 
149
            raise ValueError("stmt is neither a string nor callable")
 
150
 
 
151
    def print_exc(self, file=None):
 
152
        """Helper to print a traceback from the timed code.
 
153
 
 
154
        Typical use:
 
155
 
 
156
            t = Timer(...)       # outside the try/except
 
157
            try:
 
158
                t.timeit(...)    # or t.repeat(...)
 
159
            except:
 
160
                t.print_exc()
 
161
 
 
162
        The advantage over the standard traceback is that source lines
 
163
        in the compiled template will be displayed.
 
164
 
 
165
        The optional file argument directs where the traceback is
 
166
        sent; it defaults to sys.stderr.
 
167
        """
 
168
        import linecache, traceback
 
169
        if self.src is not None:
 
170
            linecache.cache[dummy_src_name] = (len(self.src),
 
171
                                               None,
 
172
                                               self.src.split("\n"),
 
173
                                               dummy_src_name)
 
174
        # else the source is already stored somewhere else
 
175
 
 
176
        traceback.print_exc(file=file)
 
177
 
 
178
    def timeit(self, number=default_number):
 
179
        """Time 'number' executions of the main statement.
 
180
 
 
181
        To be precise, this executes the setup statement once, and
 
182
        then returns the time it takes to execute the main statement
 
183
        a number of times, as a float measured in seconds.  The
 
184
        argument is the number of times through the loop, defaulting
 
185
        to one million.  The main statement, the setup statement and
 
186
        the timer function to be used are passed to the constructor.
 
187
        """
 
188
        if itertools:
 
189
            it = itertools.repeat(None, number)
 
190
        else:
 
191
            it = [None] * number
 
192
        gcold = gc.isenabled()
 
193
        gc.disable()
 
194
        timing = self.inner(it, self.timer)
 
195
        if gcold:
 
196
            gc.enable()
 
197
        return timing
 
198
 
 
199
    def repeat(self, repeat=default_repeat, number=default_number):
 
200
        """Call timeit() a few times.
 
201
 
 
202
        This is a convenience function that calls the timeit()
 
203
        repeatedly, returning a list of results.  The first argument
 
204
        specifies how many times to call timeit(), defaulting to 3;
 
205
        the second argument specifies the timer argument, defaulting
 
206
        to one million.
 
207
 
 
208
        Note: it's tempting to calculate mean and standard deviation
 
209
        from the result vector and report these.  However, this is not
 
210
        very useful.  In a typical case, the lowest value gives a
 
211
        lower bound for how fast your machine can run the given code
 
212
        snippet; higher values in the result vector are typically not
 
213
        caused by variability in Python's speed, but by other
 
214
        processes interfering with your timing accuracy.  So the min()
 
215
        of the result is probably the only number you should be
 
216
        interested in.  After that, you should look at the entire
 
217
        vector and apply common sense rather than statistics.
 
218
        """
 
219
        r = []
 
220
        for i in range(repeat):
 
221
            t = self.timeit(number)
 
222
            r.append(t)
 
223
        return r
 
224
 
 
225
def timeit(stmt="pass", setup="pass", timer=default_timer,
 
226
           number=default_number):
 
227
    """Convenience function to create Timer object and call timeit method."""
 
228
    return Timer(stmt, setup, timer).timeit(number)
 
229
 
 
230
def repeat(stmt="pass", setup="pass", timer=default_timer,
 
231
           repeat=default_repeat, number=default_number):
 
232
    """Convenience function to create Timer object and call repeat method."""
 
233
    return Timer(stmt, setup, timer).repeat(repeat, number)
 
234
 
 
235
def main(args=None):
 
236
    """Main program, used when run as a script.
 
237
 
 
238
    The optional argument specifies the command line to be parsed,
 
239
    defaulting to sys.argv[1:].
 
240
 
 
241
    The return value is an exit code to be passed to sys.exit(); it
 
242
    may be None to indicate success.
 
243
 
 
244
    When an exception happens during timing, a traceback is printed to
 
245
    stderr and the return value is 1.  Exceptions at other times
 
246
    (including the template compilation) are not caught.
 
247
    """
 
248
    if args is None:
 
249
        args = sys.argv[1:]
 
250
    import getopt
 
251
    try:
 
252
        opts, args = getopt.getopt(args, "n:s:r:tcvh",
 
253
                                   ["number=", "setup=", "repeat=",
 
254
                                    "time", "clock", "verbose", "help"])
 
255
    except getopt.error, err:
 
256
        print err
 
257
        print "use -h/--help for command line help"
 
258
        return 2
 
259
    timer = default_timer
 
260
    stmt = "\n".join(args) or "pass"
 
261
    number = 0 # auto-determine
 
262
    setup = []
 
263
    repeat = default_repeat
 
264
    verbose = 0
 
265
    precision = 3
 
266
    for o, a in opts:
 
267
        if o in ("-n", "--number"):
 
268
            number = int(a)
 
269
        if o in ("-s", "--setup"):
 
270
            setup.append(a)
 
271
        if o in ("-r", "--repeat"):
 
272
            repeat = int(a)
 
273
            if repeat <= 0:
 
274
                repeat = 1
 
275
        if o in ("-t", "--time"):
 
276
            timer = time.time
 
277
        if o in ("-c", "--clock"):
 
278
            timer = time.clock
 
279
        if o in ("-v", "--verbose"):
 
280
            if verbose:
 
281
                precision += 1
 
282
            verbose += 1
 
283
        if o in ("-h", "--help"):
 
284
            print __doc__,
 
285
            return 0
 
286
    setup = "\n".join(setup) or "pass"
 
287
    # Include the current directory, so that local imports work (sys.path
 
288
    # contains the directory of this script, rather than the current
 
289
    # directory)
 
290
    import os
 
291
    sys.path.insert(0, os.curdir)
 
292
    t = Timer(stmt, setup, timer)
 
293
    if number == 0:
 
294
        # determine number so that 0.2 <= total time < 2.0
 
295
        for i in range(1, 10):
 
296
            number = 10**i
 
297
            try:
 
298
                x = t.timeit(number)
 
299
            except:
 
300
                t.print_exc()
 
301
                return 1
 
302
            if verbose:
 
303
                print "%d loops -> %.*g secs" % (number, precision, x)
 
304
            if x >= 0.2:
 
305
                break
 
306
    try:
 
307
        r = t.repeat(repeat, number)
 
308
    except:
 
309
        t.print_exc()
 
310
        return 1
 
311
    best = min(r)
 
312
    if verbose:
 
313
        print "raw times:", " ".join(["%.*g" % (precision, x) for x in r])
 
314
    print "%d loops," % number,
 
315
    usec = best * 1e6 / number
 
316
    if usec < 1000:
 
317
        print "best of %d: %.*g usec per loop" % (repeat, precision, usec)
 
318
    else:
 
319
        msec = usec / 1000
 
320
        if msec < 1000:
 
321
            print "best of %d: %.*g msec per loop" % (repeat, precision, msec)
 
322
        else:
 
323
            sec = msec / 1000
 
324
            print "best of %d: %.*g sec per loop" % (repeat, precision, sec)
 
325
    return None
 
326
 
 
327
if __name__ == "__main__":
 
328
    sys.exit(main())