我将for
循环中的一个大对象传递给一个函数,并在该函数中访问另一个循环中的对象的属性,因为这似乎是最好的方法。然而,我的速度减慢了近1000倍,因此我将对象的传递更改为传递所需的属性,现在它工作正常。
传递的对象是由clr
导入的二进制对象,而不是python对象。
但是当我进行如下所示的独立测试时,我会得到完全相反的结果。
这是我的测试:
class test_Obj():
def __init__(self):
self.x = 34
self.y = 34
self.z = 34
class test_Obj2():
def __init__(self):
self.x2 = test_Obj()
self.y2 = test_Obj()
self.z2 = test_Obj()
def test1(test_Obj2):
res = list()
for i in range(100000):
res.append(test_Obj2.z2.z)
return res
def test2(z):
res = list()
for i in range(100000):
res.append(z)
return res
def test3():
res = list()
start_time = time()
for i in range(1000):
res.append(test1(test_Obj2()))
end_time = time()
print end_time - start_time
start_time = time()
for i in range(1000):
res.append(test2(test_Obj2().z2.z))
end_time = time()
print end_time - start_time
,我得到的输出如下
>>> import temp as t
>>> t.test3()
94.2169342041
423.085632324
有人可以帮我理解这种行为吗?
答案 0 :(得分:0)
您的第一个测试会创建一个包含1000个元素的列表,每个元素都是100,000个整数的列表。这是100,000,000个列表元素。
第二个测试创建了另外1000个100,000个整数的列表,它存储在前1000个列表的末尾。
这可能会慢一点,因为你的实际内存耗尽并开始分页到光盘,或者因为垃圾收集已经启动并且必须检查以前的100,000,000个元素以将它们标记为仍然可访问,或者可能只是因为正在运行其他东西在你的系统上。
使用timeit
作为Martijn的建议,并确保在第一次测试后清理(或者更好地运行两个单独的脚本)。我的猜测是,当所有其他条件相同时,传入对象的速度会稍慢一些(因为在test2中有200,000,000个属性查找而不是2000)。