Python 3.7引入了dataclasses来存储数据。我正在考虑采用这种新方法,该方法比命令更井井有条。
但是我有一个疑问。 Python将键转换为dict上的哈希,这使得查找键和值的速度更快。数据类实现类似的东西吗?
哪个更快?为什么?
答案 0 :(得分:5)
python中的所有类实际上都在内部使用字典来存储其属性,正如您可以在文档中阅读here一样。有关python类(以及更多事物)如何工作的更深入的参考,您还可以查看python's datamodel上的文章,特别是有关自定义类的部分。
因此,从字典到数据类的迁移通常不会造成性能损失。但是最好使用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
基本数据类
# 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
在这里我们可以看到使用类确实有一些开销。对于类的创建来说,它要慢很多(〜5倍),但是只要您不打算每秒创建和抛弃数据类多次,就不必关心它。
属性访问可能是更重要的指标,虽然数据类再次变慢(约1.25倍),但这次并没有那么多。
如果您认为这仍然太慢,可以使用slots而不是字典来存储其属性来调整数据类(或任何类,实际上):
时隙数据类
# 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
通过使用这种模式,我们可以节省更多的纳秒。在这一点上,至少在属性访问方面,字典应该不再有明显的区别,您可以使用数据类的优点而不会影响速度。