I was attempting to determine, via iPython's %%timeit
mechanism, whether set.remove
is faster than list.remove
when a conundrum came up.
I could do
In [1]: %%timeit
a_list = list(range(100))
a_list.remove(50)
and then do the same thing but with a set
. However, this would include the overhead from the list
/set
construction. Is there a way to re-build the list
/set
each iteration but only time the remove
method?
CodePudding user response:
Put your setup code on the same line to create any names or precursor operations you need!
https://ipython.org/ipython-doc/dev/interactive/magics.html#magic-timeit
In cell mode, the statement in the first line is used as setup code (executed but not timed) and the body of the cell is timed. The cell body has access to any variables created in the setup code.
%%timeit setup_code
...
Unfortunately only a single run can be done as it does not re-run the setup code
%%timeit -n1 x = list(range(100))
x.remove(50)
Surprisingly, this doesn't accept a string like timeit
expects, so combined with the single run requirement, I'd still go to timeit
with a string setup and repeat it manually if lots of setup or a statistically higher precision is needed
See @Kelly Bundy's much more precise answer for more!
CodePudding user response:
Alternatively, using the timeit
module with more repetitions and some statistics:
list: 814 ns ± 3.7 ns
set: 152 ns ± 1.6 ns
list: 815 ns ± 4.3 ns
set: 154 ns ± 1.6 ns
list: 817 ns ± 4.3 ns
set: 153 ns ± 1.6 ns
Code (Try it online!):
from timeit import repeat
from statistics import mean, stdev
for _ in range(3):
for kind in 'list', 'set':
ts = repeat('data.remove(50)', f'data = {kind}(range(100))', number=1, repeat=10**5)
ts = [t * 1e9 for t in sorted(ts)[:1000]]
print('%4s: = ns ± %.1f ns' % (kind, mean(ts), stdev(ts)))