Python数据结构的性能:定义内部方法还是外部方法



我有一个方法,它依赖于存储在dict中的几个值。也许这是一个微观优化,但最好在方法内部还是外部定义dict?还是这真的很重要?

示例代码:

_values = {'a': 2, 'b': 3}
def add_1(val):
return _values[val] + 1

或者:

def add_1(val):
_values = {'a': 2, 'b': 3}
return _values[val] + 1

然后,该代码将被导入并在其他地方使用(即不同的文件(~from methods import *

在每种情况下,口译员在试图找到dict时所走的路径是什么?我的理解是,在方法范围之外查找dict的成本略高。

第一个版本更快。每次调用第二个版本时,它都会从头开始创建一个新的字典。这是一个小的额外时间,但它仍然是额外的时间:

In [20]: v1 = {'a': 2, 'b': 3}
In [21]: def add_1(val):
...:     return v1[val] + 1
In [22]: %timeit add_1('a')
128 ns ± 0.989 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [23]: def add_2(val):
...:     v2 = {'a': 2, 'b': 3}
...:     return v2[val] + 1
In [24]: %timeit add_2('b')
206 ns ± 3.15 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

每个正常函数对象都有一个对定义它的模块的全局命名空间的引用。第一个选项将在该命名空间中执行查找。当模块第一次执行时,字典本身将只创建一次。由于引用存储在add_1.__globals__中,因此即使仅使用import methods.add_1from methods import add_1,查找也能正常工作。在"LEGB"中查找"G(global("可能略慢于"L(local(",但我预计这里不会有太大差异。

第二个选项在每次运行函数时创建一个新的dictionary对象。我希望这将超过在本地命名空间中保留引用的任何查找优化。这种方法提供的一个优点是,它使您的字典实际上是不可变的。

虽然我直觉上希望第一个选项运行得更快,但你必须为这个微观优化做一个基准测试才能确定。我怀疑这与您的Python实现、计算机体系结构、字典大小以及许多其他因素有很大关系。

最新更新