Как установить начальный размер словаря в Python?
Я помещаю около 4 миллионов различных ключей в словарь Python.
Создание этого словаря занимает около 15 минут и потребляет около 4 ГБ памяти на моей машине. После того, как словарь полностью создан, запрос словаря выполняется быстро.
Я подозреваю, что создание словаря настолько ресурсоемким, что словарь очень часто перефразируется (так как он растет чрезвычайно).
Можно ли создать словарь в Python с некоторым начальным размером или числом ведра?
Мой словарь указывает от числа к объекту.
class MyObject(object):
def __init__(self):
# some fields...
d = {}
d[i] = MyObject() # 4M times on different key...
Ответы
Ответ 1
С проблемами производительности всегда лучше всего измерить. Вот некоторые тайминги:
d = {}
for i in xrange(4000000):
d[i] = None
# 722ms
d = dict(itertools.izip(xrange(4000000), itertools.repeat(None)))
# 634ms
dict.fromkeys(xrange(4000000))
# 558ms
s = set(xrange(4000000))
dict.fromkeys(s)
# Not including set construction 353ms
Последняя опция не производит никакого изменения размера, она просто копирует хеши из набора и увеличивает ссылки. Как вы можете видеть, изменение размера не занимает много времени. Вероятно, ваше создание объекта происходит медленно.
Ответ 2
Я пробовал:
a = dict.fromkeys((range(4000000)))
Он создает словарь с 4 000 000 записей за 3 секунды. После этого значения настроек очень быстры. Так что я думаю, что dict.fromkey определенно способ пойти.
Ответ 3
Если вы знаете C, вы можете взглянуть на dictobject.c и Заметки по оптимизации словарей. Там вы увидите параметр PyDict_MINSIZE:
PyDict_MINSIZE. В настоящее время установлено значение 8.
Этот параметр определен в dictobject.h. Поэтому вы можете изменить его при компиляции Python, но это, вероятно, плохая идея.
Ответ 4
Вы можете попытаться отделить хеширование ключей от содержимого, заполняемого dict.fromkeys
classmethod. Он создаст dict
известного размера со всеми значениями, по умолчанию либо None
, либо значением по вашему выбору. После этого вы можете перебирать его, чтобы заполнить значения. Это поможет вам время фактического хэширования всех ключей. Не уверен, что вы сможете значительно увеличить скорость.
Ответ 5
Если ваши данные нужны/могут быть сохранены на диске, возможно, вы можете сохранить свои данные в базе данных BSDDB или использовать Cpickle, чтобы загрузить/сохранить ваш dictionnary
Ответ 6
Вы инициализируете все ключи новыми "пустыми" экземплярами того же типа? Невозможно ли написать defaultdict или что-то, что создаст объект при его доступе?