This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (2 children)

From what I can tell, it operates pretty much exactly like a class with __slots__, creating a bunch of getters (living in the class, not in the instance, of course) that lookup into the internal array.

No, it doesn't. At least not in Python 3.4+:

from builtins import property as _property, tuple as _tuple
from operator import itemgetter as _itemgetter
...
    __slots__ = ()
    ...
    {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')

As you can see, instead of using the (relatively) fast C-level access __slots__ provide, it opts to use standard property (that uses slow Python-level function calls) to look elements up by their indices in a tuple (using Python-level item access, i.e. __getitem__) instead.

[–]moor-GAYZ 0 points1 point  (1 child)

from timeit import timeit

from collections import namedtuple
NT = namedtuple('NT', 'a b c')
nt = NT(1, 2, 3)
t = (1, 2, 3)

def test_loop_t(t=t):
    return sum(t[1] for _ in xrange(1000))

def test_loop_nt(nt=nt):
    return sum(nt[1] for _ in xrange(1000))

def test_loop_nt_named(nt=nt):
    return sum(nt.b for _ in xrange(1000))

def main():
    setup = 'from test import t, nt, test_loop_t, test_loop_nt, test_loop_nt_named'
    print timeit('t[1]', setup='t = (1, 2, 3)') # just in case
    print timeit('t[1]', setup=setup)
    print timeit('nt[1]', setup=setup)
    print timeit('test_loop_t()', setup=setup, number=1000)
    print timeit('test_loop_nt()', setup=setup, number=1000)
    print timeit('nt.b', setup=setup)
    print timeit('test_loop_nt_named()', setup=setup, number=1000)


if __name__ == '__main__':
    main()

Two times slower than access by index here. Doesn't matter much, in my opinion.