Производительность в итерации словаря Python 3: dict [key] и dict.items () - PullRequest
0 голосов
/ 19 ноября 2018

Что из этого быстрее и почему? Или они одинаковые? Отличается ли ответ от каких-либо условий (размер словаря, тип данных и т. Д.)?

Традиционные:

for key in dict:
    x = dict[key]
    x = key

Hipster:

for key, value in dict.items():
    y = value
    y = key

Я не видел точного дубликата, но если он есть, я был бы рад указать на него.

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Этот код должен пройти через словарь только один раз, чтобы извлечь из него все:

for key, value in dict.items():

Этот код проходит весь словарь один раз, но получает только ключи:

for key in dict:
    x = dict[key]

Затем для каждого ключа он должен снова войти в словарь, чтобы найти значение. Итак, это должно быть медленнее.

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

0 голосов
/ 19 ноября 2018

Оказывается, на самом деле существуют порядки величины различий.

Я не знаю много о тестировании производительности, но я пытался создать 3 диктанта разного размера, каждый из которых былподмножество большего диктата.Затем я пропустил все три диктанта через две функции (Традиционный против Хипстера).Затем я сделал это 100 раз.

Размеры словарей (количество пар ключ-значение) для dict1, dict2 и dict3 равны 1000, 50000, 500000 соответственно.

Кажется, чточтобы быть существенным отличием, с d.items(), как правило, быстрее и d.items(), будучи WAY быстрее в меньших словарях.Это соответствует ожиданиям (Python обычно награждает «питонический» код).

Результаты:

--d[key]--
dict1 -- mean: 0.0001113555802294286, st. dev: 1.9951038526222054e-05
dict2 -- mean: 0.01669296698019025, st. dev: 0.019088713496142
dict3 -- mean: 0.2553815016898443, st. dev: 0.02778986771642094

--d.items()--
dict1 -- mean: 6.005059978633653e-05, st. dev: 1.1960199272812617e-05
dict2 -- mean: 0.00507106617995305, st. dev: 0.009871762371401046
dict3 -- mean: 0.07369932165958744, st. dev: 0.023440325168927384

Код ( repl.it ), обеспечивающий результаты:

import timeit
import random
import statistics

def traditional(dicty):

  for key in dicty:
    x = dicty[key]
    x = key

def hipster(dicty):

  for key, value in dicty.items():
    y = value
    y = key

def generate_random_dicts():
  random_dict1, random_dict2, random_dict3 = {}, {}, {}

  for _ in range(1000):
    key = generate_random_str_one_to_ten_chars()
    val = generate_random_str_one_to_ten_chars()
    random_dict1[key] = val
    random_dict2[key] = val
    random_dict3[key] = val

  for _ in range(49000):
    key = generate_random_str_one_to_ten_chars()
    val = generate_random_str_one_to_ten_chars()
    random_dict2[key] = val
    random_dict3[key] = val

  for _ in range(450000):
    key = generate_random_str_one_to_ten_chars()
    val = generate_random_str_one_to_ten_chars()
    random_dict3[key] = val

  return [random_dict1, random_dict2, random_dict3]

def generate_random_str_one_to_ten_chars():
  ret_str = ""
  for x in range(random.randrange(1,10,1)):
    ret_str += chr(random.randrange(40,126,1))
  return ret_str

dict1, dict2, dict3 = generate_random_dicts()

test_dicts = [dict1, dict2, dict3]

times = {}
times['traditional_times'] = {}
times['hipster_times'] = {}

for _ in range(100):

  for itr, dictx in enumerate(test_dicts):
    start = timeit.default_timer() 
    traditional(dictx)
    end = timeit.default_timer() 
    time = end - start
    try:
      times['traditional_times'][f"dict{itr+1}"].append(time)
    except KeyError:
      times['traditional_times'][f"dict{itr+1}"] = [time]

    start = timeit.default_timer() 
    hipster(dictx)
    end = timeit.default_timer() 
    time = end - start
    try:
      times['hipster_times'][f"dict{itr+1}"].append(time)
    except KeyError:
      times['hipster_times'][f"dict{itr+1}"] = [time]

print("--d[key]--")
for x in times['traditional_times'].keys():
  ltimes = times['traditional_times'][x]
  mean = statistics.mean(ltimes)
  stdev = statistics.stdev(ltimes)
  print(f"{x} -- mean: {mean}, st. dev: {stdev}\n\n")

print("--d.items()--")
for x in times['hipster_times'].keys():
  ltimes = times['hipster_times'][x]
  mean = statistics.mean(ltimes)
  stdev = statistics.stdev(ltimes)
  print(f"{x} -- mean: {mean}, st. dev: {stdev}")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...