在我的项目中,我必须检查一个值是否是两个值之一。由于我可以使用if or
语句或if in
语句来实现这一点,而且我不知道这两个语句中哪一个运行得更快,因此我运行了以下代码来检查它们各自的性能:
import time
import datetime
from scipy.stats import ttest_ind
def if_in(t):
bln = False
for z in range(400):
if z % 100 == 0: print("test1", z)
starttime = time.time()
for x in range(1000000):
for i in range(5):
if i in [2, 4]:
bln = True
t.append(time.time() - starttime)
return t
def if_or(t):
bln = False
for z in range(400):
if z % 100 == 0: print("test2", z)
starttime = time.time()
for x in range(1000000):
for i in range(5):
if i == 2 or i == 4:
bln = True
t.append(time.time() - starttime)
return t
st = time.time()
times1 = if_in([])
times2 = if_or([])
t, p = ttest_ind(times1, times2)
print("\nTotal execution time:", str(datetime.timedelta(seconds=time.time() - st)))
t1mean = sum(times1) / len(times1)
t2mean = sum(times2) / len(times2)
print("Test1 mean:", t1mean, "\nTest2 mean:", t2mean)
print("\nT-test p-score:", p)
其中印刷:
Test1 mean: 0.47915725767612455
Test2 mean: 0.46851890563964843
T-test p-score: 0.001033983121482868
p值表示in
和or
语句循环的执行时间之间的差异是显著的
为什么会有这种差异?对于“or”方法,我假设当第一个条件被认为是真的时,进一步的检查将停止。我再次假设,“in”方法也是如此。但是,其中一个确实比另一个跑得快
此外,这会持续更多的情况吗?例如,何时应将i
检查为100个值之一
您的观察结果存在多个问题
让我们暂时忘记谁是“赢家”
第一个最重要的问题是,您观察到一些统计上显著的偏离值的平均值,并将其概括为某部分代码执行速度的反映。 虽然这对于特定的代码运行可能是正确的,但是对于一般的方法来说,没有什么可说的,因为在这个级别上,您的度量主要是由操作系统驱动的波动。 我很有信心(我自己也观察到了这一点),多次运行这段代码将为每次运行带来不同的赢家
第二个问题是您使用的^{} 不太适合基准测试。您可能应该使用^{} ,即使这样,它也可能不适合测量如此短的计时
第三个问题是,您的数据不支持您的结论,因为与
if_or()
相关的tmean2
实际上小于与if_in
相关的tmean1
请注意,实际测量您建议的两个选项之间哪一个更快是非常有挑战性的(可能是无关的)
相反,研究第二个问题是有趣的,即对于模式
x == y0 or x == y1
等的较大重复,在容器上使用in
是否更快让我们研究一下(使用IPython
%timeit
魔术计时)对于不同数量的短路:正如您所看到的,通过足够的短路,
or
解决方案与任何给定容器上的in
一样快,但一般来说,使用set()
是一个更好的选择,因为它证明了自己的快速性(因为它有O(1)
查找时间,而没有tuple
或list
查找时间)与短路赌注无关最后,为了了解
or
速度较慢的原因,让我们使用dis
分解if_or()
和if_in_set()
:if_or()
if_in_set()
您可以看到,包含多个相对昂贵的
COMPARE_OP
调用的冗长的第三个if_or()
块被单个COMPARE_OP
调用所取代。 Python的优化机制正在冻结容器相关问题 更多 >
编程相关推荐