Python 3.7引入了dataclasses来存储数据。我正在考虑转向这种比dict更有条理,更有条理的新方法。
但我怀疑。 Python将键转换为切片上的哈希值,这使得查找键和值的速度更快。数据类实现类似的东西?
哪一个更快,为什么?
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而不是字典来存储其属性来调整您的数据类(或任何类)。
Slotted dataclass
# 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
通过使用这种模式,我们可以减少几纳秒。此时,至少关于属性访问,不再对字典有明显的区别,您可以在不影响速度的情况下使用数据类的优点。