Можно ли дать Python dict начальную емкость (и это полезно) - PullRequest
12 голосов
/ 11 июня 2010

Я заполняю диктон питона примерно 10 000 000 предметов.Мое понимание слова dict (или хеш-таблиц) состоит в том, что когда в них попадает слишком много элементов, необходимо изменить размер, операция, которая стоит довольно много времени.хранить в нем хотя бы n элементов, чтобы он мог выделять память с самого начала?Или эта оптимизация не принесет пользы моей скорости бега?

(И нет, я не проверял, из-за этого ли медленность моего маленького скрипта, я бы сейчас не стал, как это делать.Однако это то, что я бы сделал в Java, установив начальную емкость HashSet правильно)

Ответы [ 2 ]

18 голосов
/ 11 июня 2010

Во-первых, я слышал, что вы можете установить размер словаря при инициализации, но я никогда не видел никакой документации или PEP, описывающих, как это будет сделано.

Имея это в виду, япровел анализ вашего количества предметов, описанных ниже.Хотя каждый раз для изменения размера словаря может потребоваться некоторое время, я бы порекомендовал двигаться вперед, не беспокоясь о нем, по крайней мере до тех пор, пока вы не сможете протестировать его производительность.и фактор изменения размера.Размер словаря изменится, когда он будет заполнен на 2/3 при добавлении элемента, поместив его над отметкой 2/3.Ниже 50 000 элементов он увеличится в 4 раза, выше этого показателя в 2 раза. Используя вашу оценку в 10 000 000 элементов (от 2 ^ 23 до 2 ^ 24), ваш словарь изменит свой размер в 15 раз (в 7 раз ниже 50k,8 раз выше).Другое изменение размера произойдет сразу после 11 10000 *.

Изменение размера и замена текущих элементов в хеш-таблице действительно занимает некоторое время, но мне интересно, заметите ли вы это с тем, что происходит в коде поблизости.Я просто собрал набор времени, сравнивающий вставки в пяти местах вдоль каждой границы с размерами словаря от 2 ^ 3 до 2 ^ 24, и добавления «границы» в среднем на 0,4 наносекунды длиннее, чем добавления «без границ».Это на 0,17% дольше ... вероятно, приемлемо.Минимум для всех операций составлял 0,20585 микросекунд, а максимальный - 0,2412 микросекунд.

Надеюсь, это проницательно, и если вы все же проверите производительность своего кода, пожалуйста, продолжайте редактирование!Моим основным ресурсом по внутренним компонентам словаря были великолепные выступления Брэндона Роудса на PyCon 2010: The Mighty Dictionary

2 голосов
/ 26 марта 2015

Да, вы можете, и вот решение, которое я нашел в вопросе другого человека, который также относится к вашему:

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

это разные способы инициализации словаря определенного размера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...