我希望Python match
/case
对每种情况都有相同的时间访问,但似乎我错了。有什么好的解释吗?
让我们使用以下示例:
def match_case(decimal):
match decimal:
case '0':
return "000"
case '1':
return "001"
case '2':
return "010"
case '3':
return "011"
case '4':
return "100"
case '5':
return "101"
case '6':
return "110"
case '7':
return "111"
case _:
return "NA"
并定义一个快速工具来测量时间:
import time
def measure_time(funcion):
def measured_function(*args, **kwargs):
init = time.time()
c = funcion(*args, **kwargs)
print(f"Input: {args[1]} Time: {time.time() - init}")
return c
return measured_function
@measure_time
def repeat(function, input):
return [function(input) for i in range(10000000)]
如果我们对每个用例运行10000000
次,则次数如下:
for i in range(8):
repeat(match_case, str(i))
# Input: 0 Time: 2.458001136779785
# Input: 1 Time: 2.36093807220459
# Input: 2 Time: 2.6832823753356934
# Input: 3 Time: 2.9995620250701904
# Input: 4 Time: 3.5054492950439453
# Input: 5 Time: 3.815168857574463
# Input: 6 Time: 4.164452791213989
# Input: 7 Time: 4.857251167297363
只是想知道为什么访问时间是不同的。这是不是优化了也许一个查找表?注意,我不感兴趣的其他方式有相等的访问时间(即字典)。
4条答案
按热度按时间bmvo0sr51#
PEP 622开发“match\case”功能是为了替换如下代码:
代码如下:
虽然在最原始的情况下,它可能相当于dict查找,但通常情况下并不是这样的。Case模式被设计成看起来像普通的python代码,但实际上它们隐藏了
isinsance
和len
调用,并且当你看到像Node()
这样的代码时,它们不会执行你所期望执行的。本质上,这等价于if ... elif ... else语句链。注意,与前面提出的switch语句不同,预先计算的调度字典语义在这里不适用。
lkaoscv72#
我尝试使用另一个函数调用
match_if
来重复您的实验:看起来如果我们使用if,elif,else语句的效率不如match / case方法。下面是我的结果:
结果匹配/病例:
关于为什么会出现这些结果,我没有一个精确的答案,但这个实验表明,如果我们使用if语句,比match case稍长一点。
bqf10yzr3#
我来晚了,但我觉得我可以添加一些有用的东西到这个线程。
不久前,我在Medium上发表了一篇关于Python的match case性能的文章,分析了生成的字节码,并进行了基准测试和比较。如果你愿意,你可以阅读文章here。我认为这是值得你花时间的。
不过,我在这里总结一下。
许多编程语言都把switch-case语句当作if-else序列来实现,有时switch-case语句可以被优化成一个高效的查找表,但并不总是这样。
在Python中,从来不执行这种优化,因此总是导致一系列的条件检查。
从文章中可以看到if-else和match-case之间的速度比较:
如你所见,它们几乎相等。
另外,如果您分解这两个语句,您会发现它们生成几乎相同的字节代码。
需要指出的一个区别是,if-else检查调用对象的
__eq__()
方法,而match-case在内部进行比较。最后,这里有一个基准测试,它还包括一个哈希表(字典):
因此,如果你对性能很感兴趣,你应该使用哈希表。尽管match-case类似于C风格的switch case,但它不是:match-case用于结构模式匹配,而不是用于替换性能哈希表和查找表。
55ooxyrt4#
从python 3.10开始,可以使用match... case和默认选项(所谓的通配符),用
case _
表示文件https://docs.python.org/3/whatsnew/3.10.html#simple-pattern-match-to-a-literal
性能
如果您关心match... case与if.. elif... else的性能,则它们相同。
正如您所看到的,Python的(andilabs:看汇编指令)match-case语句只是一系列隐藏的比较,就像if-else方法一样。这就是为什么当我们对这两种方法进行基准测试时,它们的性能是一样的。
来源:https://betterprogramming.pub/pythons-match-case-is-too-slow-if-you-don-t-understand-it-8e8d0cf927d
使用字典方法如何?
关于使用旧pythonic方法切换字典的旁注-它比较慢,因此对于python3.10+和
match... case
,它可能会成为真正的老式方法。