Python: 创建小列表多次有多耗费性能?

9 投票
8 回答
561 浏览
提问于 2025-04-15 20:12

我在使用Python的时候,总是遇到一个小烦恼:

选项1:

代码看起来更整洁,但如果多次调用do_something(),速度可能会变慢,因为每次调用的时候a_list都会被重新创建。

def do_something():    
  a_list = ["any", "think", "whatever"]    
  # read something from a_list

选项2:

代码看起来不太好,但效率更高(可以避免重复创建a_list)。

a_list = ["any", "think", "whatever"]    
def do_something():    
  # read something from a_list

你觉得怎么样?

8 个回答

4

选项 3:

def do_something(a_list = ("any", "think", "whatever")):
    read something from a_list

选项 3 和选项 1 的比较:

在我看来,这两种写法的可读性是一样的(虽然评论区有人可能有不同的看法!:-))。你甚至可以把选项 3 写成这样:

def do_something(
    a_list = ("any", "think", "whatever")):
    read something from a_list

这样写的话,阅读起来几乎没有差别。不过,与选项 1 不同的是,选项 3 只在定义 do_something 的时候定义了一次 a_list。这正是我们想要的。

选项 3 和选项 2 的比较:

尽量避免使用全局变量。选项 3 让你可以做到这一点。而选项 2 随着时间的推移,或者如果其他人来维护这段代码,a_list 的定义可能会和 def do_something 分开。这可能不是大问题,但我觉得这样有点不太好。

4

如果不必要的话,千万不要重复创建同样的东西。这是一个很简单的优化方法,我个人觉得第二个例子一点也不难看。

有人可能会说,不用太在意这些小优化,但我觉得这么简单的问题应该马上解决。我可不想看到你的应用程序为了追求一种随意的“代码美感”,而创建不必要的多个副本。:)

16

这有什么不好呢?

你提到的列表里的内容是不是总是常量,就像你举的例子那样?如果是的话:从Python 2.4版本开始,新的Python会通过计算常量表达式并保存结果来进行优化,但这只有在它是一个元组的时候才会这样做。所以你可以把它改成元组。或者你也可以不去担心这些小细节。

下面是一个常量列表和一个常量元组的例子:

>>> def afunc():
...    a = ['foo', 'bar', 'zot']
...    b = ('oof', 'rab', 'toz')
...    return
...
>>> import dis; dis.dis(afunc)
  2           0 LOAD_CONST               1 ('foo')
              3 LOAD_CONST               2 ('bar')
              6 LOAD_CONST               3 ('zot')
              9 BUILD_LIST               3
             12 STORE_FAST               0 (a)

  3          15 LOAD_CONST               7 (('oof', 'rab', 'toz'))
             18 STORE_FAST               1 (b)

  4          21 LOAD_CONST               0 (None)
             24 RETURN_VALUE
>>>

撰写回答