为什么通过字段名访问 namedtuple 比访问 class 的成员变量慢?
Why is accessing a namedtuple by field name slower than accessing a class's member variable?
我们正在做一些实验来比较 classes 和命名元组中的访问时间并观察到一些奇怪的东西。
import time
from collections import namedtuple as namedtuple
class myclass(object):
def __init__(self, _name, _dob, _value):
self.name = _name
self.dob = _dob
self.value = _value
randomperson1 = myclass( 'randomperson', 10102000, 10.45 )
person = namedtuple( 'person', 'name dob value' )
randomperson2 = person( 'randomperson', 10102000, 10.45)
在使用 ipython 的 timeit 时,观察到以下情况:
%timeit randomperson1.name,randomperson1.value,randomperson1.dob
10000000 loops, best of 3: 125 ns per loop
%timeit randomperson2.name,randomperson2.value,randomperson2.dob
1000000 loops, best of 3: 320 ns per loop
%timeit randomperson2[0],randomperson2[1],randomperson2[2]
10000000 loops, best of 3: 127 ns per loop
为什么通过字段名访问 namedtuple 比访问 class 的成员变量慢得多?有什么办法可以加快速度吗?
那是因为在 namedtuple
中属性 name, value, dob
不是实例上的简单属性。它们实际上变成了更复杂的东西
collections.py
_field_template = '''\
{name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')
'''
例如
dob = property(itemgetter(2), doc='Alias for field number 2')
所以你可以看到它上面有额外的层。创建 namedtuple
的人决定以牺牲 CPU 效率为代价来保持内存效率的一致性。这就是原因。
当您创建自己的自定义 class 模拟时,可以很容易地观察到这一点:
from operator import itemgetter
class CustomTuple(tuple):
my_attr = property(itemgetter(0))
test_tuple = CustomTuple([1])
现在测量对 test_tuple.my_attr
的访问。你应该得到几乎相同的结果。
我们正在做一些实验来比较 classes 和命名元组中的访问时间并观察到一些奇怪的东西。
import time
from collections import namedtuple as namedtuple
class myclass(object):
def __init__(self, _name, _dob, _value):
self.name = _name
self.dob = _dob
self.value = _value
randomperson1 = myclass( 'randomperson', 10102000, 10.45 )
person = namedtuple( 'person', 'name dob value' )
randomperson2 = person( 'randomperson', 10102000, 10.45)
在使用 ipython 的 timeit 时,观察到以下情况:
%timeit randomperson1.name,randomperson1.value,randomperson1.dob
10000000 loops, best of 3: 125 ns per loop
%timeit randomperson2.name,randomperson2.value,randomperson2.dob
1000000 loops, best of 3: 320 ns per loop
%timeit randomperson2[0],randomperson2[1],randomperson2[2]
10000000 loops, best of 3: 127 ns per loop
为什么通过字段名访问 namedtuple 比访问 class 的成员变量慢得多?有什么办法可以加快速度吗?
那是因为在 namedtuple
中属性 name, value, dob
不是实例上的简单属性。它们实际上变成了更复杂的东西
collections.py
_field_template = '''\
{name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')
'''
例如
dob = property(itemgetter(2), doc='Alias for field number 2')
所以你可以看到它上面有额外的层。创建 namedtuple
的人决定以牺牲 CPU 效率为代价来保持内存效率的一致性。这就是原因。
当您创建自己的自定义 class 模拟时,可以很容易地观察到这一点:
from operator import itemgetter
class CustomTuple(tuple):
my_attr = property(itemgetter(0))
test_tuple = CustomTuple([1])
现在测量对 test_tuple.my_attr
的访问。你应该得到几乎相同的结果。