在 python 中制作不可变对象的修改副本的最快方法

Fastest way to make a modified copy of an immutable object in python

如果我有一个存储一些不可变对象(如整数)的元组对象,并且我需要尽可能创建此元组的修改版本 efficiently/fast,那么最好的方法是什么?

这是我目前拥有的一个简化示例。

orig_tuple = (1, 0, 0)
new_tuple = (some_function(element) for element in orig_tuple)

这是最快的吗?列表理解会增加很多开销吗?

增加开销的是函数调用,而不是 listcomp。而这个returns是生成器,不是元组,注意不是同一个

要对您的想法进行基准测试或分析,请尝试使用 Python 中内置的 distimeit 库。我在 Windows 7 x64.

上使用 Python 2.7
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)

出品:

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

如您所见,创建该生成器似乎要快得多。 method_two 是我能想到的唯一其他方法来完成您想要完成的事情。如果您有任何其他想法,请测试它们并在需要反馈时编辑您的问题。