简体   繁体   English

Python中替代开关的性能差异

[英]Performance difference in alternative switches in Python

I have read a few articles around alternatives to the switch statement in Python. 我已经阅读了一些关于Python中switch语句的替代方法的文章。 Mainly using dicts instead of lots of if's and elif's. 主要使用dicts代替很多if和elif。 However none really answer the question: is there one with better performance or efficiency? 然而,没有人真正回答这个问题:是否有更好的性能或效率? I have read a few arguments that if's and elifs would have to check each statement and becomes inefficient with many ifs and elif's. 我已经阅读了一些论据,如果和elifs必须检查每个语句并且使用许多ifs和elif变得低效。 However using dicts gets around that, but you end up having to create new modules to call which cancels the performance gain anyways. 然而,使用dicts可以解决这个问题,但是你最终必须创建新的模块才能调用,从而取消性能提升。 The only difference in the end being readability. 唯一不同的是可读性。

Can anyone comment on this, is there really any difference in the long run? 任何人都可以对此发表评论,从长远来看真的有什么不同吗? Does anyone regularly use the alternative? 有没有人经常使用替代品? Only reason I ask is because I am going to end up having 30-40 elif/if's and possibly more in the future. 我要问的唯一原因是因为我最终会得到30-40 elif / if's,将来可能更多。 Any input is appreciated. 任何输入都表示赞赏。 Thanks. 谢谢。

dict 's perfomance is typically going to be unbeatable, because a lookup into a dict is going to be O(1) except in rare and practically never-observed cases (where they key involves user-coded types with lousy hashing;-). dict的性能通常是无与伦比的,因为对dict的查找将是O(1),除了在罕见的和几乎从未观察到的情况下(他们的密钥涉及用户编码的类型与糟糕的散列;-)。 You don't have to "create new modules" as you say, just arbitrary callables, and that creation, which is performed just once to prep the dict, is not particularly costly anyway -- during operation, it's just one lookup and one call, greased lightning time. 你不必像你说的那样“创建新的模块”,只需要任意的callables,而且只需执行一次就可以完成dict的创建,无论如何都不是特别昂贵 - 在操作过程中,它只是一次查找和一次调用,闪电般的闪电时间。

As others have suggested, try timeit to experiment with a few micro-benchmarks of the alternatives. 正如其他人的建议,尝试timeit与替代品的几个微基准测试实验。 My prediction: with a few dozen possibilities in play, as you mention you have, you'll be slapping your forehead about ever considering anything but a dict of callables!-) 我的预测:有几十个可能的游戏,正如你所提到的那样,你会打你的额头, 除了一个关于callables的词典之外什么都不考虑! - )

If you find it too hard to run your own benchmarks and can supply some specs, I guess we can benchmark the alternatives for you, but it would be really more instructive if you tried to do it yourself before you ask SO for help!-) 如果您发现运行自己的基准测试并且可以提供一些规格太难了,我想我们可以为您量身定做替代方案,但如果您在向SO寻求帮助之前尝试自己做,那将会更有启发性! - )

Your concern should be about the readability and maintainability of the code, rather than its efficiency. 您应该关注代码的可读性和可维护性,而不是其效率。 This applies in most scenarios, and particularly in the one you describe now. 这适用于大多数情况,尤其是您现在描述的情景。 The efficiency difference is likely to be negligible (you can easily check it with a small amount of benchmarking code), but 30-40 elif's are a warning sign - perhaps something can be abstracted away and make the code more readable. 效率差异可能是微不足道的(您可以使用少量的基准测试代码轻松检查它),但30-40 elif是一个警告标志 - 也许可以抽象出来并使代码更具可读性。 Describe your case, and perhaps someone can come up with a better design. 描述你的情况,也许有人可以想出更好的设计。

With all performance/profiling questions, the right answer is "test each case yourself for your specific needs." 对于所有性能/分析问题,正确答案是“根据您的特定需求自行测试每个案例”。

One great tool for this is timeit which you can learn about in the python docs . 这样做的一个很好的工具是timeit ,你可以了解在python文档

In general I have seen no performance issues related to using a dictionary in place of other languages switch statement. 一般来说,我没有看到与使用字典代替其他语言的switch语句相关的性能问题。 My guess would be that the comparison in performance would depend on the number of alternatives. 我的猜测是性能的比较将取决于替代品的数量。 Who knows, there may be a tipping point where one becomes better than the other. 谁知道,可能有一个转折点,一个变得比另一个好。

If you (or anyone else) tests it, feel free to post your results. 如果您(或其他任何人)对其进行测试,请随时发布您的结果。

Times when you'd use a switch in many languages you would use a dict in Python. 当你在许多语言中使用开关时,你会在Python中使用dict。 A switch statement, if added to Python (it's been considered), would not be able to give any real performance gain anyways. 如果将switch语句添加到Python(已被考虑过),则无法提供任何实际的性能提升。

dicts are used ubiquitously in Python. dicts在Python中无处不在。 CPython dicts are an insanely-efficient, robust hashtable implementation. CPython dicts是一种非常有效,强大的哈希表实现。 Lookup is O(1), as opposed to traversing an elif chain, which is O(n). Lookup是O(1),而不是遍历elif链,即O(n)。 (30-40 probably doesn't qualify as big enough for this to matter tons anyways). (30-40可能没有足够大的资格来解决这个问题)。 I am not sure what you mean about creating new modules to call, but using dicts is very scalable and easy. 我不确定你对创建新模块的意思是什么,但使用dicts是非常可扩展和容易的。

As for actual performance gain, that is impossible to really tackle effectively abstractly. 至于实际的性能提升,这是不可能真正有效地抽象地解决。 Write your code in the most straightforward and maintainable way (you're using Python forgoshsakes!) and then see if it's too slow. 以最简单和可维护的方式编写代码(您正在使用Python forgoshsakes!)然后查看它是否太慢。 If it is, profile it and find out what places it needs to be sped up to make a real difference. 如果是,请对其进行分析,找出需要加速的地方,以实现真正的改变。

I think a dict will gain advantage over the alternative sequence of if statements as the number of cases goes up, since the key lookup only requires one hash operation. 我认为随着案例数量的增加,dict将优于if语句的替代序列,因为键查找只需要一个哈希操作。 Otherwise if you only have a few cases, a few if statements are better. 否则,如果您只有少数情况,那么一些if语句会更好。 A dict is probably a more elegant solution for what you are doing. 对于你正在做的事情,dict可能是一个更优雅的解决方案。 Either way, the performance difference wont really be noticeable in your case. 无论哪种方式,性能差异在您的情况下都不会明显。

I ran a few benchmarks (see here ). 我运行了几个基准测试(见这里 )。 Using lists of function pointers is fastest,if your keys are sequential integers. 如果您的键是顺序整数,则使用函数指针列表是最快的。 For the general case: Alex Martelli is right, dictionary are fastest. 对于一般情况:Alex Martelli是对的,字典是最快的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM