我之所以这样问是因为我感到很惊讶——我认为一个
namedtuple
将会有更多的开销。
(背景是我在内存中缓存一个大型Django查询,并发现Django对象的大小是.values()
的100倍。然后我想知道namedtuple
版本的对象会有多少开销,使我仍然可以使用.
访问属性。比较小是不是我预期的。)#!/usr/bin/env python
from pympler.asizeof import asizeof
from collections import namedtuple
import random
import string
QTY = 100000
class Foz(object):
pass
dicts = [{'foo': random.randint(0, 10000),
'bar': ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(32)]),
'baz': random.randrange(10000),
'faz': random.choice([True, False]),
'foz': Foz()} for _ in range(QTY)]
print "%d dicts: %d" % (len(dicts), asizeof(dicts))
# https://dev59.com/fFcP5IYBdhLWcg3wu8a1
MyTuple = namedtuple('MyTuple', sorted(dicts[0]))
tuples = [MyTuple(**d) for d in dicts]
print "%d namedtuples: %d" % (len(tuples), asizeof(tuples))
print "Ratio: %.01f" % (float(asizeof(tuples)) / float(asizeof(dicts)))
运行中,
$ ./foo.py
100000 dicts: 75107672
100000 namedtuples: 56707472
Ratio: 0.8
单个元组甚至更小,可能是由于 list
的开销:
$ ./foo.py
1 dicts: 1072
1 namedtuples: 688
Ratio: 0.6
是哈希表数组的开销吗?但是一个namedtuple
也需要属性的哈希表吧?是pympler
不准确吗?
asizeof
计算)应该在大量项目上平均分配。 - rrauenza__slots__
- wimnamedtuple
不需要哈希表。它是一个元组。它的特点是为了节省内存。这就是它的用例,并且使得与元组一起工作更易读/自我说明。 - juanpa.arrivillaga