Python添加,为什么不可变变量更快?

时间:2015-11-12 21:20:03

标签: python performance

我正在学习python中的mutable / immutable概念。我认为,为了积累,可变列表将比不可变变量更快,因为它发生在#34;就位#34;。请看我的代码:

import time


def use_immutable_variable():
    t = time.time()
    accumulator = 0
    for x in range(1000000):
        accumulator += x
    return time.time() - t


def use_mutable_array():
    t = time.time()
    accumulators = [0]
    for x in range(1000000):
        accumulators[0] += x
        #accumulators[0].__add__(x)
    return time.time() - t

times = []
for i in range(10):
    times.append(use_immutable_variable())
print("use_immutable_variable: %s" % (sum(times)/float(len(times))))

times = []
for i in range(10):
    times.append(use_mutable_array())
print("use_mutable_array     : %s" % (sum(times)/float(len(times))))

结果是:

use_immutable_variable: 0.1034714937210083
use_mutable_array     : 0.166017746925354

我想这不是python中累加器的正确方法。这个问题的关键在于,我认为可变列表方法比不可变列表方法更快,因为可变元素的更改发生在#34;就位#34;。但我的测试表明,不可变的方法更快。有人能解释一下吗?提前谢谢!

2 个答案:

答案 0 :(得分:2)

如果要将项目附加到数组中,使用列表而不是元组是有意义的,但这不是你在这里做的。您的“可变”解决方案只是在访问整数值之前添加了一个额外的中间步骤,整数值本身就是一个不可变对象。

答案 1 :(得分:1)

正如评论中的oseiskar评论,这与可变性无关。但通过反汇编相关代码可以很容易地显示出差异:

import dis

lst = [0]
def incr_in_list():
    lst[0] += 1

n = 0
def incr():
    n += 1

dis.dis(incr_in_list)
3           0 LOAD_GLOBAL              0 (lst)
            3 LOAD_CONST               1 (0)
            6 DUP_TOP_TWO
            7 BINARY_SUBSCR
            8 LOAD_CONST               2 (1)
            11 INPLACE_ADD
            12 ROT_THREE
            13 STORE_SUBSCR
            14 LOAD_CONST               0 (None)
            17 RETURN_VALUE

dis.dis(incr)
8           0 LOAD_FAST                0 (n)
            3 LOAD_CONST               1 (1)
            6 INPLACE_ADD
            7 STORE_FAST               0 (n)
            10 LOAD_CONST               0 (None)
            13 RETURN_VALUE

+=的工作少得多(无需访问列表中的变量)并调用LOAD_FASTSTORE_FAST而不是从列表中提取值,递增它(在这两种情况下INPLACE_ADD并将其存回。