Python: 如何测试IF语句对Dictionary Case语句的效率?
Python: How to test efficiency of IF statement to a Dictionary Case statement?
我希望能够在 Python 中测试 IF 语句对字典 case 语句 hack 的效率。由于没有 case 语句,我目前使用的是字典方法。好像是这样....
self.options = {"0": self.racerOne,
"1": self.racerTwo,
"2": self.racerThree,
"3": self.racerFour,
"0f": self.racerFinish,
"1f": self.racerFinish,
"2f": self.racerFinish,
"3f": self.racerFinish,
"x": self.emptyLine,
"t": self.raceTime,
"G": self.letsGo,
"CD": self.countDown,
"C": self.emptyLine,
}
真实世界的数据会有所不同,但我有办法 运行 进行受控测试并在 6.4 秒内读取 688 行流数据。
我也读过这篇文章 post:Python Dictionary vs If Statement Speed 我也将检查 cProfile 方法。
对于与字典选项相比如何准确测量 IF 语句,是否有人有任何其他建议?高效我想这意味着使用最少的处理能力并且可以更好地跟上流。
在这 6.4 秒的时间里,我读取了每一行流数据,对其进行解析、评估,然后以可视化方式实时显示。我认为在 Win 或 OSX 系统上 运行ning 我的应用程序不会有太大不同,但它也必须 运行 在 Raspberry Pi 上处理力量有限
提前致谢。
听起来好像你要优化的主要领域不会是这个语句。
但是,出于好奇,我还是检查了一下。在您链接到的问题中给出的直观答案是 python 字典是作为哈希表实现的。查找应按项目数量的 O(1) 左右缩放。 If 语句沿着你展示的内容将按 O(n) 缩放,因为每个语句将按顺序完成。 运行 1000 个随机数通过使用每个函数的函数,有 2 到 1000 个选择,我得到以下时间(每个选择的 y 刻度以秒为单位,并且是对数刻度)。如果链是蓝色的,则字典查找是绿色的。 x 刻度表示可能的选择数量:
可以看出,查找快,并且比长 if 语句链快。
即使对于短链,在此代码中,查找仍然更快或大致相同:
但请注意这里的时间。我们谈论的是我计算机上每个选择的 亚微秒 范围内的时间:对于少量选择大约 600ns。那时,开销可能来自像函数调用这样简单的事情。另一方面,如果您有大量可能的选择,那么最好使用的东西应该非常清楚。
上面的代码如下。它使用 numpy 来跟踪所有时间。对于像这样的简单计时问题,通常最简单的方法是只使用 time.time() 来获取您想做的任何事情之前和之后的时间值。对于非常快的事情,您需要循环多次并取平均次数。
我应该补充一点,我创建 if 语句链的方式有点邪恶。有可能这样做(使用 exec 语句)函数在某种程度上没有以相同的方式优化:我不是 python 内部的专家。
import numpy as np
import time
def createdictfun(n):
optdict = { x: 2*x for x in range(0,n) }
def dictfun(x):
return optdict[x]
return dictfun
def createiffun(n):
s="def iffun(x):\n"
s+=" if x==0: return 0\n"
for i in range(1,n):
s+=" elif x=={}: return {}\n".format(i,i*2)
s+=" else: raise ValueError\n"
exec s
return iffun
ntry=10
maxchoice=1000
trialsize=1000
ifvals=np.zeros((maxchoice,2))
dictvals=np.zeros((maxchoice,2))
ns=np.arange(1,maxchoice)
for n in ns:
ift = np.zeros(ntry)
dictt = np.zeros(ntry)
vals=np.random.randint(0,n,size=trialsize)
iffun = createiffun(n)
dictfun = createdictfun(n)
for trial in range(0,ntry):
ts=time.time()
for x in vals:
iffun(x)
ift[trial]=time.time()-ts
ts=time.time()
for x in vals:
dictfun(x)
dictt[trial]=time.time()-ts
ifvals[n,0]=np.mean(ift)/trialsize
ifvals[n,1]=np.std(ift)/trialsize
dictvals[n,0]=np.mean(dictt)/trialsize
dictvals[n,1]=np.std(dictt)/trialsize
print str(n)+" ",
我希望能够在 Python 中测试 IF 语句对字典 case 语句 hack 的效率。由于没有 case 语句,我目前使用的是字典方法。好像是这样....
self.options = {"0": self.racerOne,
"1": self.racerTwo,
"2": self.racerThree,
"3": self.racerFour,
"0f": self.racerFinish,
"1f": self.racerFinish,
"2f": self.racerFinish,
"3f": self.racerFinish,
"x": self.emptyLine,
"t": self.raceTime,
"G": self.letsGo,
"CD": self.countDown,
"C": self.emptyLine,
}
真实世界的数据会有所不同,但我有办法 运行 进行受控测试并在 6.4 秒内读取 688 行流数据。
我也读过这篇文章 post:Python Dictionary vs If Statement Speed 我也将检查 cProfile 方法。
对于与字典选项相比如何准确测量 IF 语句,是否有人有任何其他建议?高效我想这意味着使用最少的处理能力并且可以更好地跟上流。
在这 6.4 秒的时间里,我读取了每一行流数据,对其进行解析、评估,然后以可视化方式实时显示。我认为在 Win 或 OSX 系统上 运行ning 我的应用程序不会有太大不同,但它也必须 运行 在 Raspberry Pi 上处理力量有限
提前致谢。
听起来好像你要优化的主要领域不会是这个语句。
但是,出于好奇,我还是检查了一下。在您链接到的问题中给出的直观答案是 python 字典是作为哈希表实现的。查找应按项目数量的 O(1) 左右缩放。 If 语句沿着你展示的内容将按 O(n) 缩放,因为每个语句将按顺序完成。 运行 1000 个随机数通过使用每个函数的函数,有 2 到 1000 个选择,我得到以下时间(每个选择的 y 刻度以秒为单位,并且是对数刻度)。如果链是蓝色的,则字典查找是绿色的。 x 刻度表示可能的选择数量:
可以看出,查找快,并且比长 if 语句链快。
即使对于短链,在此代码中,查找仍然更快或大致相同:
但请注意这里的时间。我们谈论的是我计算机上每个选择的 亚微秒 范围内的时间:对于少量选择大约 600ns。那时,开销可能来自像函数调用这样简单的事情。另一方面,如果您有大量可能的选择,那么最好使用的东西应该非常清楚。
上面的代码如下。它使用 numpy 来跟踪所有时间。对于像这样的简单计时问题,通常最简单的方法是只使用 time.time() 来获取您想做的任何事情之前和之后的时间值。对于非常快的事情,您需要循环多次并取平均次数。
我应该补充一点,我创建 if 语句链的方式有点邪恶。有可能这样做(使用 exec 语句)函数在某种程度上没有以相同的方式优化:我不是 python 内部的专家。
import numpy as np
import time
def createdictfun(n):
optdict = { x: 2*x for x in range(0,n) }
def dictfun(x):
return optdict[x]
return dictfun
def createiffun(n):
s="def iffun(x):\n"
s+=" if x==0: return 0\n"
for i in range(1,n):
s+=" elif x=={}: return {}\n".format(i,i*2)
s+=" else: raise ValueError\n"
exec s
return iffun
ntry=10
maxchoice=1000
trialsize=1000
ifvals=np.zeros((maxchoice,2))
dictvals=np.zeros((maxchoice,2))
ns=np.arange(1,maxchoice)
for n in ns:
ift = np.zeros(ntry)
dictt = np.zeros(ntry)
vals=np.random.randint(0,n,size=trialsize)
iffun = createiffun(n)
dictfun = createdictfun(n)
for trial in range(0,ntry):
ts=time.time()
for x in vals:
iffun(x)
ift[trial]=time.time()-ts
ts=time.time()
for x in vals:
dictfun(x)
dictt[trial]=time.time()-ts
ifvals[n,0]=np.mean(ift)/trialsize
ifvals[n,1]=np.std(ift)/trialsize
dictvals[n,0]=np.mean(dictt)/trialsize
dictvals[n,1]=np.std(dictt)/trialsize
print str(n)+" ",