为什么按字段名访问namedtuple比访问类的成员变量要慢?

时间:2015-07-03 06:08:38

标签: python dictionary namedtuple

我们正在做一些实验来比较类和命名元组中的访问时间,并观察到一些奇怪的事情。

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比访问一个类的成员变量要慢得多?有什么方法可以加快速度吗?

1 个答案:

答案 0 :(得分:3)

那是因为namedtuple属性name, value, dob不是实例上的简单属性。它们实际上变成了更复杂的东西

<强> collections.py

_field_template = '''\
    {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')
'''

e.g。

dob = property(itemgetter(2), doc='Alias for field number 2')

因此,您可以看到其上有其他图层。创建namedtuple的人决定他们希望以CPU效率为代价来保持内存效率的一致性。这就是原因。

当您创建自己的自定义类时,可以很容易地观察到这一点:

from operator import itemgetter

class CustomTuple(tuple):
    my_attr = property(itemgetter(0))

test_tuple = CustomTuple([1])

现在衡量对test_tuple.my_attr的访问权限。你应该得到几乎相同的结果。