Python 3 - 哪个访问数据更快:数据类还是字典?

Python 3 - Which one is faster for accessing data: dataclasses or dictionaries?

Python 3.7 引入了 dataclasses 来存储数据。我正在考虑转向这种比字典更有条理、结构更合理的新方法。

但我有疑问。 Python 将键转换为字典上的哈希值,这使得查找键和值的速度更快。数据类实现类似的东西?

哪个更快,为什么?

python 中的所有 class 实际上都在后台使用字典来存储它们的属性,您可以阅读 here in the documentation. For a more in-depth reference on how python classes (and many more things) work, you can also check out the article on python's datamodel,特别是关于自定义的部分 classes.

所以一般来说,从字典转移到数据classes 应该不会有性能损失。但最好使用 timeit 模块来确保:


基线

# dictionary creation
$ python -m timeit "{'var': 1}"
5000000 loops, best of 5: 52.9 nsec per loop

# dictionary key access
$ python -m timeit -s "d = {'var': 1}" "d['var']"
10000000 loops, best of 5: 20.3 nsec per loop

基础数据class

# dataclass creation
$ python -m timeit -s "from dataclasses import dataclass" -s "@dataclass" -s "class A: var: int" "A(1)" 
1000000 loops, best of 5: 288 nsec per loop

# dataclass attribute access
$ python -m timeit -s "from dataclasses import dataclass" -s "@dataclass" -s "class A: var: int" -s "a = A(1)" "a.var" 
10000000 loops, best of 5: 25.3 nsec per loop

这里我们可以看出使用classes确实有一些开销。对于 class 创建,它相当多(慢 ~5 倍),但只要您不打算创建和丢弃数据,您就不必太在意它class es 每秒多次。

属性访问可能是更重要的指标,虽然数据classes 再次变慢(~1.25 倍),但这次并没有那么多。

如果您认为这仍然有点太慢,您可以调整数据class(或任何 classes,真的)使用 slots 而不是字典来存储他们的属性:


时隙数据class

# dataclass creation
$ python -m timeit -s "from dataclasses import dataclass" -s "@dataclass" -s "class A: __slots__ = ('var',); var: int" "A(1)" 
1000000 loops, best of 5: 242 nsec per loop

# dataclass attribute access
$ python -m timeit -s "from dataclasses import dataclass" -s "@dataclass" -s "class A: __slots__ = ('var',); var: int" -s "a = A(1)" "a.var"
10000000 loops, best of 5: 21.7 nsec per loop

通过使用这种模式,我们可以再缩短几纳秒。在这一点上,至少在属性访问方面,字典应该不再有明显的区别,您可以在不影响速度的情况下利用数据classes 的优势。