Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 为什么Python枚举速度慢?_Performance_Python 3.x_Enums - Fatal编程技术网

Performance 为什么Python枚举速度慢?

Performance 为什么Python枚举速度慢?,performance,python-3.x,enums,Performance,Python 3.x,Enums,今天,我尝试将我的一些“最终”值(我的类的成员)从一个类外包给一个枚举。我运行了我编写的单元测试,并注意到这些测试需要比以前更长的时间才能完成。当我把这些“最终”值放回课堂时,一切又回到了原来的速度。下面是我在枚举中访问它们的示例: class SpecialCharacters(Enum): TONE_NUMBERS = ["0", "1", "2", "3", "4"] 这样访问它: SpecialCharacters.TONE_NUMBERS.value 在类中访问值的示例:

今天,我尝试将我的一些“最终”值(我的类的成员)从一个类外包给一个枚举。我运行了我编写的单元测试,并注意到这些测试需要比以前更长的时间才能完成。当我把这些“最终”值放回课堂时,一切又回到了原来的速度。下面是我在枚举中访问它们的示例:

class SpecialCharacters(Enum):

    TONE_NUMBERS = ["0", "1", "2", "3", "4"]
这样访问它:

SpecialCharacters.TONE_NUMBERS.value
在类中访问值的示例:

self.TONE_NUMBERS
因此,我想知道为什么我的测试在将值放入枚举时需要3倍(!)的时间。这应该是一个简单的呼叫另一个类的成员,但我想这不会有太大的区别

(外包它们的目的是,它们可用于其他类,而其他类不必访问与它们无关的类。)


我的python版本是3.4。

这是python 3.4枚举中的一个已知错误:


Python 3.5中已经“修复”了这一问题,因此枚举属性查找速度仅比正常速度慢3倍,而不是20倍。

要回答问题
为什么?

Enum
的最初设计是将成员设置为虚拟属性。这意味着它们没有保存在
Enum
类字典中,这意味着每次可能的查找都必须先失败,然后对类调用
\uuuuu getattr\uuuu
,并找到成员

所以基本上有很多繁忙的工作


修复方法是在可能的情况下(大多数情况下)将成员放入类字典。

在测试中访问这些值的次数是多少?数以百万计的?几千万?需要的解引用步骤越多,解引用的速度就越慢。但这不应该是一个明显的数量,除非你非常、非常、非常频繁地访问这些。解引用不应该影响我必须乘以的因素,以获得更长的运行时间,因为它总是以相同的方式访问值,而且解引用不太可能消耗这么多时间,取消引用的时间是实际算法的2倍。@Zephir,Enum类主要用于中的示例中所示的普通值,而不是数组?另请参见,这是一个显著的改进。3倍的时间仍然很重要,但在这方面我没有与其他编程语言进行比较,因此它可能很常见。不幸的是,big
IntFlag
enum在组合属性时非常慢-我想使用它们而不是frozenset(减少内存)但是,当一个IntFlag拥有约10000名成员时,要想获得几百个int Flag需要很多时间。可能和你有关?无论如何,还是要感谢enum模块:)@Mr_and_Mrs_D:希望在3.10中速度会更快,但我承认我没有考虑一个包含数千个可能值的标志集。你在建模什么?我有一个算法,它使用整数集字典作为基础数据结构,所以检查成员资格,然后执行并集和交集。扩展到更大的数据集时,这些集合占用了大量内存,其中一些会导致相等的集合是不同的对象。由于我认为联合和交集应该使用标志快速,并且它们是单例,所以我给了它一个旋转-将int映射到
范围(1,num_keys+1)
,并为每个索引创建一个IntFlag。或者,在这些(可能是交叉点)中输入数字键~10k需要花费很长时间