gpt4 book ai didi

python |为什么访问实例属性比本地慢?

转载 作者:太空狗 更新时间:2023-10-29 22:05:37 24 4
gpt4 key购买 nike

import timeit

class Hello():
def __init__(self):
self.x = 5
def get_local_attr(self):
x = self.x
# 10x10
x;x;x;x;x;x;x;x;x;x;
x;x;x;x;x;x;x;x;x;x;
x;x;x;x;x;x;x;x;x;x;
x;x;x;x;x;x;x;x;x;x;
x;x;x;x;x;x;x;x;x;x;
x;x;x;x;x;x;x;x;x;x;
x;x;x;x;x;x;x;x;x;x;
x;x;x;x;x;x;x;x;x;x;
x;x;x;x;x;x;x;x;x;x;
x;x;x;x;x;x;x;x;x;x;
def get_inst_attr(self):
# 10x10
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;
self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;self.x;

if __name__ == '__main__':
obj = Hello()
print('Accessing Local Attribute:', min(timeit.Timer(obj.get_local_attr)
.repeat(repeat=5)))
print('Accessing Instance Attribute:', min(timeit.Timer(obj.get_inst_attr)
.repeat(repeat=5)))

我电脑的结果:

访问本地属性:0.686281020000024

访问实例属性:3.7962001440000677

为什么会这样?此外,在使用实例变量之前对其进行本地化是一种好习惯吗?

最佳答案

每次 python 查找一个变量时,你都会付出一点(LOAD_FAST 操作码)。每次查找现有对象的属性时,您都要多付一点钱(LOAD_ATTR 操作码)。例如

>>> def f1(self):
... x = self.x
... x
...
>>> def f2(self):
... self.x
... self.x
...
>>> dis.dis(f1)
2 0 LOAD_FAST 0 (self)
3 LOAD_ATTR 0 (x)
6 STORE_FAST 1 (x)

3 9 LOAD_FAST 1 (x)
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
>>> dis.dis(f2)
2 0 LOAD_FAST 0 (self)
3 LOAD_ATTR 0 (x)
6 POP_TOP

3 7 LOAD_FAST 0 (self)
10 LOAD_ATTR 0 (x)
13 POP_TOP
14 LOAD_CONST 0 (None)
17 RETURN_VALUE
>>>

即使您不知道如何阅读 python 反汇编字节码,您也可以看到为 f2 所做的工作比为 f1 做的更多。

另请注意,并非所有操作码都相同。 LOAD_FAST基本上是本地范围内的数组查找(因此顾名思义,它是快速的)。 LOAD_ATTR是(另一方面)有点慢,因为它转换为(通常)执行字典查找的函数调用 (__getattribute__)。


就什么是“最佳实践”而言,做最容易阅读的事情。我认为使用 self 是很常见的做法,除非您证明通过避免它可以显着提高性能,但我认为这不是硬性规定。

关于 python |为什么访问实例属性比本地慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28597014/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com