Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
2193 commits
Select commit Hold shift + click to select a range
0f84bd4
Update pystruct + array
coolreader18 Oct 20, 2020
59169aa
Use a static type for struct.error
coolreader18 Oct 20, 2020
026f396
Use std::os::raw::c_* instead of libc::c_* for wasm compat
coolreader18 Oct 20, 2020
0aa177d
Merge pull request #2307 from ChJR/feature/format_float
coolreader18 Oct 26, 2020
00920ba
Add socket sendfile function
rodrigocam Oct 26, 2020
264f49b
give up on adding good javascript support, clean up UI instead
mireille-raad Oct 27, 2020
3c9ad23
Merge pull request #2297 from RustPython/coolreader18/rework-pystruct
coolreader18 Oct 27, 2020
eaf4bad
fix array with float
qingshi163 Oct 27, 2020
a656c51
Add os sendfile function and python test
rodrigocam Oct 27, 2020
01e6f73
Remove socket sendfile wrong implementation
rodrigocam Oct 27, 2020
a8d579d
Add guard clause to check if os has sendfile function
rodrigocam Oct 27, 2020
a64ecbf
Process headers and trailers as array of byte buffers
rodrigocam Oct 27, 2020
b3ee56c
obligatory readme
mireille-raad Oct 28, 2020
a742d0d
update ui and test features
mireille-raad Oct 28, 2020
4002b38
add snippets
mireille-raad Oct 28, 2020
6de2dc6
Add macro call to allow function up to seven parameters
rodrigocam Oct 28, 2020
7d45672
Skip unrelated test in test_os
coolreader18 Oct 28, 2020
ad3922a
Skip shutil test
coolreader18 Oct 28, 2020
8cdbccd
Use Python 3.8 for CI
coolreader18 Oct 28, 2020
5de8527
Merge pull request #2312 from qingshi163/array-float
coolreader18 Oct 28, 2020
7b8066d
Specify python version for pipenv
coolreader18 Oct 28, 2020
525ff49
Merge pull request #2311 from rodrigocam/master
coolreader18 Oct 28, 2020
d562b02
Expose sys module constants in rust level
youknowone Oct 20, 2020
babebf0
fix math.acosh
hyperbora Oct 30, 2020
249f121
Merge pull request #2315 from hyperbora/fix-math-acosh
coolreader18 Oct 30, 2020
b7a73fd
Capitalize boolean constants for dis
coolreader18 Oct 30, 2020
dc3a300
Unify format_float_as_exponent to clarify
ChJR Oct 31, 2020
29859b4
Separate Formatting decimal point case in cformat
ChJR Oct 31, 2020
d4af9d0
Reimpl cformat to suit for bytes
qingshi163 Nov 1, 2020
3ebff18
fix cformat bug
qingshi163 Nov 2, 2020
697d6ed
Merge pull request #2294 from RustPython/coolreader18/pyobj-constants
youknowone Nov 2, 2020
cd415c6
Merge pull request #2295 from youknowone/sysmodule
youknowone Nov 2, 2020
8aea12b
Fix unused variables warnings
youknowone Nov 2, 2020
b1a94c2
Merge pull request #2319 from youknowone/fix-warnings
youknowone Nov 2, 2020
bd64412
Try skipping caching on macos
coolreader18 Oct 28, 2020
a87ce5b
Skip more tests for macos
coolreader18 Oct 28, 2020
56b46b7
Enable test_importlib
coolreader18 Oct 30, 2020
1dccad9
Fix pathlib import on windows
coolreader18 Oct 30, 2020
9105c44
Add more winreg functions
coolreader18 Nov 1, 2020
606d819
Skip some importlib tests on windows + fix weird errors, hopefully?
coolreader18 Nov 2, 2020
02daac6
Try fixing macos deadlock
coolreader18 Nov 2, 2020
68af202
Give support funcs names
coolreader18 Nov 2, 2020
b5b15e0
os.unlink can remove junctions on windows
coolreader18 Nov 3, 2020
e4f446e
Re-add test_importlib to windows skiplist
coolreader18 Nov 3, 2020
7773562
Reimpl format
qingshi163 Nov 3, 2020
84fa251
Generic CFormatPart
qingshi163 Nov 3, 2020
991be82
Merge pull request #2313 from mainsail-org/mir/notebook
coolreader18 Nov 3, 2020
b18814a
Rework CFormatSpec format
qingshi163 Nov 4, 2020
ac4e5b8
Merge pull request #2314 from RustPython/coolreader18/no-cache-mac
youknowone Nov 6, 2020
6ba5880
Add a PyThreadMutex lock type
coolreader18 Oct 12, 2020
7beb932
Distinguish between to_index and to_index_opt
coolreader18 Oct 12, 2020
0745725
Implement buffered io sans buffering
coolreader18 Oct 12, 2020
a1ca535
Make bufferoptions.format a Cow<'static, str>
coolreader18 Oct 13, 2020
5f07081
Make PyType.tp_name() more efficient
coolreader18 Oct 13, 2020
473d538
Make Buffered{Reader,Writer} actually buffered
coolreader18 Oct 13, 2020
ff55a2e
WIP seek
coolreader18 Oct 14, 2020
3d19d97
Expose classes as attributes
coolreader18 Oct 28, 2020
4db7a23
Add/rename vm.obj_len, obj_len_opt
coolreader18 Nov 6, 2020
374a956
Misc changes; exception chaining, PyBytesLike::into_buffer
coolreader18 Nov 6, 2020
5ddb678
Add memory::RcBuffer
coolreader18 Nov 6, 2020
0dc8154
Finish up buffered io
coolreader18 Nov 6, 2020
402594f
Update io.py to CPython 3.8.3
coolreader18 Nov 6, 2020
3f6504c
Add _pyio, test.test_io from CPython 3.8.3
coolreader18 Nov 6, 2020
d2a302c
Skip tests in test_io
coolreader18 Nov 6, 2020
0b9beeb
Merge pull request #2318 from qingshi163/bytes-format
coolreader18 Nov 6, 2020
1d6b32c
Fix clippy/wasm errors
coolreader18 Nov 6, 2020
60d917c
Don't lock textio while calling buffer methods
coolreader18 Nov 6, 2020
76fa447
Only define buffered.flush for writer/random
coolreader18 Nov 6, 2020
916bb4c
Fix some other tests
coolreader18 Nov 6, 2020
9433126
Skip test_io on windows
coolreader18 Nov 7, 2020
17e0e75
Merge pull request #2323 from RustPython/coolreader18/buffer-io
coolreader18 Nov 7, 2020
b3851c8
Split the ast from the parser, remove compiler dep on parser
coolreader18 Nov 2, 2020
4528f17
compiler/porcelain wrapper
coolreader18 Nov 3, 2020
70907ba
Fix wasm + examples
coolreader18 Nov 3, 2020
f390f61
Merge pull request #2320 from RustPython/coolreader18/split-ast-parser
youknowone Nov 8, 2020
fce6e4c
Fix cell_lock, remove the RwLock<BufferOptions> from bytearray
coolreader18 Nov 8, 2020
b30ca99
Implement string interning
coolreader18 Nov 8, 2020
db976dd
Clear up format_float_as_exponent
ChJR Nov 9, 2020
fdeb817
Merge branch 'develop' into feature/format_float
ChJR Nov 9, 2020
a6805a5
Make get_options() return &BufferOptions
coolreader18 Nov 9, 2020
e95469e
Refine names for shorter code
ChJR Nov 9, 2020
6ca5321
Fix a mistake
ChJR Nov 9, 2020
8c96bd6
Unify general format of floating numbers
ChJR Nov 9, 2020
07a857b
Add tests for formatting floating numbers
ChJR Nov 9, 2020
213a335
Unify fixed-point format of floating numbers
ChJR Nov 9, 2020
31d662e
Fix nan sign bug in cformat
ChJR Nov 9, 2020
f8d47c6
Merge pull request #2324 from RustPython/coolreader18/fix-nothreading
coolreader18 Nov 9, 2020
2f232ec
Implement string interning for variable names
coolreader18 Nov 9, 2020
7586543
Add ability to use `__trunc__` to `int()`
carbotaniuman Nov 11, 2020
9657454
Fix missing parameter
carbotaniuman Nov 11, 2020
c478c64
Fix `complex()` and `float()` to user dunder methods
carbotaniuman Nov 11, 2020
ace2cb8
Fix edge cases in mod and complex division
carbotaniuman Nov 11, 2020
7bfc811
Format
carbotaniuman Nov 11, 2020
da9be2f
Fix clippy lint and unblock a test case
carbotaniuman Nov 11, 2020
49b5d37
Fix min test case by doing mroe validation
carbotaniuman Nov 11, 2020
1aa603a
Format
carbotaniuman Nov 11, 2020
3a45839
Supress clippy lint that doesn't work
carbotaniuman Nov 12, 2020
b66ed56
Format
carbotaniuman Nov 12, 2020
fb69414
unskip test_dict tests
youknowone Nov 11, 2020
9b2e0a7
unksip test_list.py
youknowone Nov 11, 2020
78ba212
unskip mapping_tests.py
youknowone Nov 11, 2020
da53f94
unskip test_asyncgen.py
youknowone Nov 11, 2020
02c05cc
unksip test_builtin.py
youknowone Nov 11, 2020
0aa1388
unskip test_class.py
youknowone Nov 11, 2020
2970af2
unskip test_exceptions.py
youknowone Nov 11, 2020
5dc6113
unskip test_glob.py
youknowone Nov 11, 2020
c37c1bb
unskip test_grammar.py
youknowone Nov 11, 2020
ef87fbe
unksip test_imp.py
youknowone Nov 11, 2020
308f831
unksip test_io.py
youknowone Nov 11, 2020
5307843
unskip test_list.py
youknowone Nov 11, 2020
867aa23
unksip test_module.py
youknowone Nov 11, 2020
5cedef3
unksip test_opcode.py
youknowone Nov 11, 2020
f907419
unskip test_raise.py
youknowone Nov 11, 2020
950ae44
unskip test_set.py
youknowone Nov 11, 2020
9e9163b
unskip test_symtable
youknowone Nov 11, 2020
52e8342
unksip test_tuple.py
youknowone Nov 11, 2020
864d255
unksip test_unicode.py
youknowone Nov 11, 2020
97304dd
unksip test_with.py
youknowone Nov 11, 2020
a97428b
Merge pull request #2327 from youknowone/unskip-tests
youknowone Nov 13, 2020
792aed3
Refactor into `min_or_max`
carbotaniuman Nov 13, 2020
5533227
Format
carbotaniuman Nov 13, 2020
135c0e5
Delete unnecessary mut
carbotaniuman Nov 13, 2020
a6f7bb8
Remove mut
carbotaniuman Nov 14, 2020
6498d79
Fix clippy maybe?
carbotaniuman Nov 14, 2020
9214f41
Use a more generic PyRefExact
coolreader18 Nov 15, 2020
e06254a
Merge pull request #2328 from carbotaniuman/fix-min
coolreader18 Nov 15, 2020
15984fc
Remove leftover comment
coolreader18 Nov 15, 2020
06e4846
Merge pull request #2326 from carbotaniuman/master
coolreader18 Nov 15, 2020
d76cb3b
Fix float power and complex division
carbotaniuman Nov 16, 2020
64b951e
Merge pull request #2325 from RustPython/coolreader18/string-intern
coolreader18 Nov 16, 2020
5227819
Add timeit.py from CPython 3.8.3
coolreader18 Nov 16, 2020
1080f06
Modify timeit.py to make it work on rustpython
coolreader18 Nov 16, 2020
6d7eae9
Add iter, iternext slots & Allow deleting slot magic methods
coolreader18 Nov 17, 2020
1f1b713
Merge pull request #2332 from RustPython/coolreader18/timeit
youknowone Nov 17, 2020
30b5fb2
Use lz-fear to get streaming decompression for bytecode
coolreader18 Nov 17, 2020
7bc6e38
Merge pull request #2333 from RustPython/coolreader18/lzfear
coolreader18 Nov 17, 2020
2b0c7f8
Return same object if exact type in int, float, complex
carbotaniuman Nov 17, 2020
e572371
Fix behavior of pow builtin
carbotaniuman Nov 17, 2020
926ac12
Format and move code in `fn pow` to `__pow__` methods
carbotaniuman Nov 18, 2020
b97aa40
Not implemented
carbotaniuman Nov 18, 2020
bd068a1
use oct number like CPython fileutils.c instead of decimal number lea…
owtotwo Nov 18, 2020
2277f41
Actually fix negative check
carbotaniuman Nov 18, 2020
27b280b
fix error again
carbotaniuman Nov 18, 2020
dcfa60b
Merge pull request #2337 from owtotwo/master
coolreader18 Nov 19, 2020
fa989d0
Format
carbotaniuman Nov 19, 2020
245ed70
Add tests for general formatting of floating numbers
ChJR Nov 19, 2020
cf2aa74
Fix trailing zeros in general formatting of floating numbers
ChJR Nov 19, 2020
8c892f2
Merge branch 'master' into feature/format_float
ChJR Nov 19, 2020
0388dac
Remove todos from tests
carbotaniuman Nov 19, 2020
4f1232a
Fix error of CI
ChJR Nov 19, 2020
0eba3ba
Prevent stack overflow from format_general which is using precision
ChJR Nov 19, 2020
3e3bd07
Fix overflow of string reverse iteration
ChJR Nov 19, 2020
6da4d97
Add more tests for general formatting of floating numbers
ChJR Nov 19, 2020
f124ec8
Fix more trailing zeros in general formatting of floating numbers
ChJR Nov 19, 2020
1c6d771
Fix clippy error with rust update
coolreader18 Nov 21, 2020
2a42772
Use a custom vtable for PyObjectRef
coolreader18 Nov 11, 2020
fafee7f
Use static_assertions to verify the safety of init_type_hierarchy
coolreader18 Nov 17, 2020
0d50118
Run tests under miri on CI
coolreader18 Nov 17, 2020
8cb1cfa
Add a bunch of comments
coolreader18 Nov 17, 2020
7a5ba0e
Update pytype to be a bit more idiomatic
coolreader18 Nov 19, 2020
31f4999
Flatten PyObject/PyInner into one struct
coolreader18 Nov 19, 2020
c5fca81
Fix regrtest results collection
coolreader18 Nov 21, 2020
3878e8e
Improve code quality
ChJR Nov 21, 2020
6484df3
Make frozenset idempotent and unskip some set tests
carbotaniuman Nov 21, 2020
24b3670
Allow clippy
carbotaniuman Nov 21, 2020
3efa8a4
Move allow attribute to specific function
coolreader18 Nov 21, 2020
f48e547
Merge pull request #2316 from ChJR/feature/format_float
coolreader18 Nov 21, 2020
fd8d9c9
Merge pull request #2335 from carbotaniuman/number-reform
coolreader18 Nov 23, 2020
6082049
Remove the need for a label_map in CodeObject
coolreader18 Nov 23, 2020
8b0e806
Fix rustpython-jit to not use label_map
coolreader18 Nov 24, 2020
749e6af
Merge pull request #2338 from carbotaniuman/frozenset
coolreader18 Nov 24, 2020
8ff7a52
Replace FuncArgs.insert with prepend_arg, optimize check_signals
coolreader18 Nov 23, 2020
085a9d4
Don't use a wildcard to prevent future mistakes
coolreader18 Nov 24, 2020
5781fa4
Merge pull request #2336 from RustPython/coolreader18/pyobjectref-cus…
coolreader18 Nov 24, 2020
cf428e1
Merge pull request #2339 from RustPython/coolreader18/mini-opts
coolreader18 Nov 24, 2020
7c32f8c
Merge pull request #2340 from RustPython/coolreader18/no-labelmap
coolreader18 Nov 24, 2020
93ec575
Merge pull request #2341 from carbotanium/test
coolreader18 Nov 24, 2020
3ff3a2c
Move function/mod.rs back to function.rs
coolreader18 Nov 27, 2020
db6b9ed
Add NamedExpression AST class
isidentical Nov 28, 2020
a71aea8
Add Slice object too
isidentical Nov 28, 2020
9676ddb
Merge pull request #2344 from isidentical/issue-2343
coolreader18 Nov 28, 2020
a382284
PEP 498 compatability: parenthesized expressions for f-strings
isidentical Nov 29, 2020
26908f1
Fix crash on lexing octal escapes bigger than u8::MAX
isidentical Nov 29, 2020
e26df2c
Apply cargo fmt
isidentical Nov 29, 2020
698ae76
Handle raw yield expressions as RHS for augmented/annotated assignments
isidentical Nov 30, 2020
d462f64
Merge pull request #2348 from isidentical/issue-2347
coolreader18 Nov 30, 2020
d141761
Directly unwrap
isidentical Nov 30, 2020
f2ba412
Remove expected failure from test_var_annot_rhs
isidentical Nov 30, 2020
0cbdb8a
Merge pull request #2346 from isidentical/issue-2345
coolreader18 Nov 30, 2020
b309004
Move main.rs to lib.rs
coolreader18 Dec 1, 2020
95c1392
Re-add main.rs using the rustpython lib
coolreader18 Dec 1, 2020
6dc93c5
Add doc comments
coolreader18 Dec 1, 2020
fbc8ebc
Merge pull request #2353 from RustPython/coolreader18/bin-lib
coolreader18 Dec 5, 2020
2c29a33
Add support for deleter on getsets
coolreader18 Nov 27, 2020
6c20c3e
Add the cell class
coolreader18 Nov 27, 2020
3d44744
Add PyTupleTyped
coolreader18 Nov 28, 2020
479610f
Move compiler snapshots
coolreader18 Dec 1, 2020
97029af
Fast locals part 1
coolreader18 Nov 28, 2020
92b8e59
Fast locals part 2
coolreader18 Nov 30, 2020
7c58f4a
Fast locals part 3
coolreader18 Dec 1, 2020
cd87f6d
Try some mini-optimizations
coolreader18 Dec 1, 2020
22e76f1
Use a boxed slice for codeobject fields
coolreader18 Dec 1, 2020
6c52c5c
Update jit to use new instructions
coolreader18 Dec 1, 2020
0fddb04
Update cranelift dependencies
coolreader18 Dec 1, 2020
150d5ae
Fix snippet test+wasm errors
coolreader18 Dec 2, 2020
2bdbe6b
Inline some hot functions
coolreader18 Dec 2, 2020
34bb5f0
Apply review suggestions
coolreader18 Dec 4, 2020
51c2ec5
Merge pull request #2355 from RustPython/coolreader18/funcvars
coolreader18 Dec 5, 2020
978260f
Update dependencies
coolreader18 Dec 5, 2020
a39775b
Fix num-bigint issue
coolreader18 Dec 6, 2020
28b5fe8
Merge pull request #2356 from RustPython/coolreader18/update-deps
youknowone Dec 6, 2020
5bbe2da
Merge pull request #2350 from isidentical/issue-2349
coolreader18 Dec 6, 2020
7db3f09
clean up clippy warnings
youknowone Dec 6, 2020
4e5dc3e
Merge pull request #2358 from youknowone/clippywanings
coolreader18 Dec 7, 2020
928fbcd
fix memoryview compare
hyperbora Dec 7, 2020
bdcdcb1
Update formatting for wasm notebook
coolreader18 Dec 1, 2020
34237ec
Add functions to js make it easier to add functions to python
coolreader18 Dec 2, 2020
a61d4b2
Improve the py<->js notebook example
coolreader18 Dec 7, 2020
a1d3f44
Add syntax highlighting for js
coolreader18 Dec 7, 2020
9e9ef0c
Add docs for injectPython et al in notebook/README
coolreader18 Dec 7, 2020
c8ee558
Misc cleanup wasm
coolreader18 Dec 7, 2020
c1fd81f
Give css/js snippets proper file extensions
coolreader18 Dec 7, 2020
d0c0b82
Merge pull request #2354 from RustPython/coolreader18/notebook-ergono…
coolreader18 Dec 7, 2020
22fa80e
notebook resonspive ipad/tablet fixes
mireille-raad Dec 8, 2020
334adf3
Remove debug print from zipimport
coolreader18 Dec 8, 2020
85e5486
wasm/notebook, responsive layout on mobile
mireille-raad Dec 9, 2020
472e535
Merge pull request #2363 from mainsail-org/mir/notebook-responsive
coolreader18 Dec 9, 2020
5788e7b
Refactor benchmarking suite to use Criterion
orf Dec 10, 2020
3a85967
Remove dependency
orf Dec 11, 2020
a788df4
Reduce to 30k
orf Dec 11, 2020
6a841c0
Remove pystone second run
orf Dec 11, 2020
184f9aa
Switch to 500
orf Dec 11, 2020
0f2bd59
Make `type()` bases arg only take tuples
carbotaniuman Nov 25, 2020
a6afbdf
Update
carbotaniuman Dec 11, 2020
9f04f37
Fix strings
orf Dec 11, 2020
a605b93
Improve benchmarks
orf Dec 11, 2020
1e4fc5c
fmt
orf Dec 11, 2020
e745805
Exclude benchmarks from flake8
orf Dec 11, 2020
c447ffd
Fix loading
orf Dec 11, 2020
bfd05ee
Switch benchmarkid
orf Dec 11, 2020
9243716
Fix clippy
carbotaniuman Dec 12, 2020
6cb89fb
Formaat
carbotaniuman Dec 12, 2020
7681892
Merge pull request #2342 from carbotaniuman/type
coolreader18 Dec 12, 2020
dde8af1
Add microbenchmarks
orf Dec 13, 2020
eb22ba1
Add microbenchmarks
orf Dec 13, 2020
7818fd2
Fix micro benchmarks
orf Dec 13, 2020
d36e150
Ignore benches
orf Dec 13, 2020
b221dbb
Allow running pystone standalone
coolreader18 Dec 13, 2020
c9a332c
Merge pull request #2367 from orf/criterion
coolreader18 Dec 14, 2020
9b76dc3
Merge pull request #2357 from hyperbora/fix-memoryview-compare
coolreader18 Dec 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add timeit.py from CPython 3.8.3
  • Loading branch information
coolreader18 committed Nov 16, 2020
commit 52278196a78f5e40e7f00e1b04208bff43554d99
375 changes: 375 additions & 0 deletions Lib/timeit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,375 @@
#! /usr/bin/env python3

"""Tool for measuring execution time of small code snippets.

This module avoids a number of common traps for measuring execution
times. See also Tim Peters' introduction to the Algorithms chapter in
the Python Cookbook, published by O'Reilly.

Library usage: see the Timer class.

Command line usage:
python timeit.py [-n N] [-r N] [-s S] [-p] [-h] [--] [statement]

Options:
-n/--number N: how many times to execute 'statement' (default: see below)
-r/--repeat N: how many times to repeat the timer (default 5)
-s/--setup S: statement to be executed once initially (default 'pass').
Execution time of this setup statement is NOT timed.
-p/--process: use time.process_time() (default is time.perf_counter())
-v/--verbose: print raw timing results; repeat for more digits precision
-u/--unit: set the output time unit (nsec, usec, msec, or sec)
-h/--help: print this usage message and exit
--: separate options from statement, use when statement starts with -
statement: statement to be timed (default 'pass')

A multi-line statement may be given by specifying each line as a
separate argument; indented lines are possible by enclosing an
argument in quotes and using leading spaces. Multiple -s options are
treated similarly.

If -n is not given, a suitable number of loops is calculated by trying
increasing numbers from the sequence 1, 2, 5, 10, 20, 50, ... until the
total time is at least 0.2 seconds.

Note: there is a certain baseline overhead associated with executing a
pass statement. It differs between versions. The code here doesn't try
to hide it, but you should be aware of it. The baseline overhead can be
measured by invoking the program without arguments.

Classes:

Timer

Functions:

timeit(string, string) -> float
repeat(string, string) -> list
default_timer() -> float

"""

import gc
import sys
import time
import itertools

__all__ = ["Timer", "timeit", "repeat", "default_timer"]

dummy_src_name = "<timeit-src>"
default_number = 1000000
default_repeat = 5
default_timer = time.perf_counter

_globals = globals

# Don't change the indentation of the template; the reindent() calls
# in Timer.__init__() depend on setup being indented 4 spaces and stmt
# being indented 8 spaces.
template = """
def inner(_it, _timer{init}):
{setup}
_t0 = _timer()
for _i in _it:
{stmt}
_t1 = _timer()
return _t1 - _t0
"""

def reindent(src, indent):
"""Helper to reindent a multi-line statement."""
return src.replace("\n", "\n" + " "*indent)

class Timer:
"""Class for timing execution speed of small code snippets.

The constructor takes a statement to be timed, an additional
statement used for setup, and a timer function. Both statements
default to 'pass'; the timer function is platform-dependent (see
module doc string). If 'globals' is specified, the code will be
executed within that namespace (as opposed to inside timeit's
namespace).

To measure the execution time of the first statement, use the
timeit() method. The repeat() method is a convenience to call
timeit() multiple times and return a list of results.

The statements may contain newlines, as long as they don't contain
multi-line string literals.
"""

def __init__(self, stmt="pass", setup="pass", timer=default_timer,
globals=None):
"""Constructor. See class doc string."""
self.timer = timer
local_ns = {}
global_ns = _globals() if globals is None else globals
init = ''
if isinstance(setup, str):
# Check that the code can be compiled outside a function
compile(setup, dummy_src_name, "exec")
stmtprefix = setup + '\n'
setup = reindent(setup, 4)
elif callable(setup):
local_ns['_setup'] = setup
init += ', _setup=_setup'
stmtprefix = ''
setup = '_setup()'
else:
raise ValueError("setup is neither a string nor callable")
if isinstance(stmt, str):
# Check that the code can be compiled outside a function
compile(stmtprefix + stmt, dummy_src_name, "exec")
stmt = reindent(stmt, 8)
elif callable(stmt):
local_ns['_stmt'] = stmt
init += ', _stmt=_stmt'
stmt = '_stmt()'
else:
raise ValueError("stmt is neither a string nor callable")
src = template.format(stmt=stmt, setup=setup, init=init)
self.src = src # Save for traceback display
code = compile(src, dummy_src_name, "exec")
exec(code, global_ns, local_ns)
self.inner = local_ns["inner"]

def print_exc(self, file=None):
"""Helper to print a traceback from the timed code.

Typical use:

t = Timer(...) # outside the try/except
try:
t.timeit(...) # or t.repeat(...)
except:
t.print_exc()

The advantage over the standard traceback is that source lines
in the compiled template will be displayed.

The optional file argument directs where the traceback is
sent; it defaults to sys.stderr.
"""
import linecache, traceback
if self.src is not None:
linecache.cache[dummy_src_name] = (len(self.src),
None,
self.src.split("\n"),
dummy_src_name)
# else the source is already stored somewhere else

traceback.print_exc(file=file)

def timeit(self, number=default_number):
"""Time 'number' executions of the main statement.

To be precise, this executes the setup statement once, and
then returns the time it takes to execute the main statement
a number of times, as a float measured in seconds. The
argument is the number of times through the loop, defaulting
to one million. The main statement, the setup statement and
the timer function to be used are passed to the constructor.
"""
it = itertools.repeat(None, number)
gcold = gc.isenabled()
gc.disable()
try:
timing = self.inner(it, self.timer)
finally:
if gcold:
gc.enable()
return timing

def repeat(self, repeat=default_repeat, number=default_number):
"""Call timeit() a few times.

This is a convenience function that calls the timeit()
repeatedly, returning a list of results. The first argument
specifies how many times to call timeit(), defaulting to 5;
the second argument specifies the timer argument, defaulting
to one million.

Note: it's tempting to calculate mean and standard deviation
from the result vector and report these. However, this is not
very useful. In a typical case, the lowest value gives a
lower bound for how fast your machine can run the given code
snippet; higher values in the result vector are typically not
caused by variability in Python's speed, but by other
processes interfering with your timing accuracy. So the min()
of the result is probably the only number you should be
interested in. After that, you should look at the entire
vector and apply common sense rather than statistics.
"""
r = []
for i in range(repeat):
t = self.timeit(number)
r.append(t)
return r

def autorange(self, callback=None):
"""Return the number of loops and time taken so that total time >= 0.2.

Calls the timeit method with increasing numbers from the sequence
1, 2, 5, 10, 20, 50, ... until the time taken is at least 0.2
second. Returns (number, time_taken).

If *callback* is given and is not None, it will be called after
each trial with two arguments: ``callback(number, time_taken)``.
"""
i = 1
while True:
for j in 1, 2, 5:
number = i * j
time_taken = self.timeit(number)
if callback:
callback(number, time_taken)
if time_taken >= 0.2:
return (number, time_taken)
i *= 10

def timeit(stmt="pass", setup="pass", timer=default_timer,
number=default_number, globals=None):
"""Convenience function to create Timer object and call timeit method."""
return Timer(stmt, setup, timer, globals).timeit(number)

def repeat(stmt="pass", setup="pass", timer=default_timer,
repeat=default_repeat, number=default_number, globals=None):
"""Convenience function to create Timer object and call repeat method."""
return Timer(stmt, setup, timer, globals).repeat(repeat, number)

def main(args=None, *, _wrap_timer=None):
"""Main program, used when run as a script.

The optional 'args' argument specifies the command line to be parsed,
defaulting to sys.argv[1:].

The return value is an exit code to be passed to sys.exit(); it
may be None to indicate success.

When an exception happens during timing, a traceback is printed to
stderr and the return value is 1. Exceptions at other times
(including the template compilation) are not caught.

'_wrap_timer' is an internal interface used for unit testing. If it
is not None, it must be a callable that accepts a timer function
and returns another timer function (used for unit testing).
"""
if args is None:
args = sys.argv[1:]
import getopt
try:
opts, args = getopt.getopt(args, "n:u:s:r:tcpvh",
["number=", "setup=", "repeat=",
"time", "clock", "process",
"verbose", "unit=", "help"])
except getopt.error as err:
print(err)
print("use -h/--help for command line help")
return 2

timer = default_timer
stmt = "\n".join(args) or "pass"
number = 0 # auto-determine
setup = []
repeat = default_repeat
verbose = 0
time_unit = None
units = {"nsec": 1e-9, "usec": 1e-6, "msec": 1e-3, "sec": 1.0}
precision = 3
for o, a in opts:
if o in ("-n", "--number"):
number = int(a)
if o in ("-s", "--setup"):
setup.append(a)
if o in ("-u", "--unit"):
if a in units:
time_unit = a
else:
print("Unrecognized unit. Please select nsec, usec, msec, or sec.",
file=sys.stderr)
return 2
if o in ("-r", "--repeat"):
repeat = int(a)
if repeat <= 0:
repeat = 1
if o in ("-p", "--process"):
timer = time.process_time
if o in ("-v", "--verbose"):
if verbose:
precision += 1
verbose += 1
if o in ("-h", "--help"):
print(__doc__, end=' ')
return 0
setup = "\n".join(setup) or "pass"

# Include the current directory, so that local imports work (sys.path
# contains the directory of this script, rather than the current
# directory)
import os
sys.path.insert(0, os.curdir)
if _wrap_timer is not None:
timer = _wrap_timer(timer)

t = Timer(stmt, setup, timer)
if number == 0:
# determine number so that 0.2 <= total time < 2.0
callback = None
if verbose:
def callback(number, time_taken):
msg = "{num} loop{s} -> {secs:.{prec}g} secs"
plural = (number != 1)
print(msg.format(num=number, s='s' if plural else '',
secs=time_taken, prec=precision))
try:
number, _ = t.autorange(callback)
except:
t.print_exc()
return 1

if verbose:
print()

try:
raw_timings = t.repeat(repeat, number)
except:
t.print_exc()
return 1

def format_time(dt):
unit = time_unit

if unit is not None:
scale = units[unit]
else:
scales = [(scale, unit) for unit, scale in units.items()]
scales.sort(reverse=True)
for scale, unit in scales:
if dt >= scale:
break

return "%.*g %s" % (precision, dt / scale, unit)

if verbose:
print("raw times: %s" % ", ".join(map(format_time, raw_timings)))
print()
timings = [dt / number for dt in raw_timings]

best = min(timings)
print("%d loop%s, best of %d: %s per loop"
% (number, 's' if number != 1 else '',
repeat, format_time(best)))

best = min(timings)
worst = max(timings)
if worst >= best * 4:
import warnings
warnings.warn_explicit("The test results are likely unreliable. "
"The worst time (%s) was more than four times "
"slower than the best time (%s)."
% (format_time(worst), format_time(best)),
UserWarning, '', 0)
return None

if __name__ == "__main__":
sys.exit(main())