Reputation: 517
If I have a tuple object which stores some immutable objects (like ints), and I need to create a modified version of this tuple as efficiently/fast as possible, what is the best way to do this?
Here is a simplified example of what I currently have.
orig_tuple = (1, 0, 0)
new_tuple = (some_function(element) for element in orig_tuple)
Is this as fast as it gets? Does the list comprehension add much overhead?
Upvotes: 1
Views: 502
Reputation: 331
To benchmark or profile your ideas, try using dis
and timeit
libraries that are built into Python. I'm using Python 2.7
on Windows 7 x64.
import copy
import dis
import timeit
def method_one():
def add_one(i):
return i+1
orig_tuple = (1, 0, 0)
new_tuple = (add_one(element) for element in orig_tuple)
def method_two():
def add_one(i):
return i+1
orig_tuple = (1, 0, 0)
new_tuple = copy.deepcopy(orig_tuple)
for i in new_tuple:
i = add_one(i)
print dis.dis(method_one)
print timeit.timeit(method_one, number=10000)
print dis.dis(method_two)
print timeit.timeit(method_two, number=10000)
Produced:
D:\Users\user>python help.py
6 0 LOAD_CONST 1 (<code object add_one at 01DA6B60, file "help.py", line 6
>)
3 MAKE_FUNCTION 0
6 STORE_DEREF 0 (add_one)
9 9 LOAD_CONST 5 ((1, 0, 0))
12 STORE_FAST 0 (orig_tuple)
10 15 LOAD_CLOSURE 0 (add_one)
18 BUILD_TUPLE 1
21 LOAD_CONST 4 (<code object <genexpr> at 01DA6CC8, file "help.py", line
10>)
24 MAKE_CLOSURE 0
27 LOAD_FAST 0 (orig_tuple)
30 GET_ITER
31 CALL_FUNCTION 1
34 STORE_FAST 1 (new_tuple)
37 LOAD_CONST 0 (None)
40 RETURN_VALUE
None
0.0088386
13 0 LOAD_CONST 1 (<code object add_one at 020C6F50, file "help.py", line 1
3>)
3 MAKE_FUNCTION 0
6 STORE_FAST 0 (add_one)
16 9 LOAD_CONST 4 ((1, 0, 0))
12 STORE_FAST 1 (orig_tuple)
17 15 LOAD_GLOBAL 0 (copy)
18 LOAD_ATTR 1 (deepcopy)
21 LOAD_FAST 1 (orig_tuple)
24 CALL_FUNCTION 1
27 STORE_FAST 2 (new_tuple)
18 30 SETUP_LOOP 26 (to 59)
33 LOAD_FAST 2 (new_tuple)
36 GET_ITER
>> 37 FOR_ITER 18 (to 58)
40 STORE_FAST 3 (i)
19 43 LOAD_FAST 0 (add_one)
46 LOAD_FAST 3 (i)
49 CALL_FUNCTION 1
52 STORE_FAST 3 (i)
55 JUMP_ABSOLUTE 37
>> 58 POP_BLOCK
>> 59 LOAD_CONST 0 (None)
62 RETURN_VALUE
None
0.1026118
As you can see, it looks like creating that generator is much faster. method_two
was the only other way I could think of off the top of my head to do what you wanted to accomplish. If you have any other ideas, test them and edit your question if you need feedback.
Upvotes: 0
Reputation: 598
Function calls is what adds overhead, not listcomp. And this returns a generator, not a tuple, be careful it is not the same.
Upvotes: 1