Почему получение первых 30 ключей словаря в двух операторах быстрее, чем в одном? - PullRequest
0 голосов
/ 09 мая 2020

Я делал для себя тест и обнаружил эту интересную вещь. Я пытаюсь получить первые 30 ключей словаря, и я написал три способа их получения:

import time
dic = {str(i): i for i in range(10 ** 6)}

start_time = time.time()
x = list(dic.keys())[0:30]
print(time.time() - start_time)

start_time = time.time()
y = list(dic.keys())
x = y[0:30]
print(time.time() - start_time)

start_time = time.time()
z = dic.keys()
y = list(z)
x = y[0:30]
print(time.time() - start_time)

Результат:

0,015970945358276367 0,010970354080200195 0,01691460609436035

Удивительно, но второй способ намного быстрее! Есть мысли по этому поводу?

Ответы [ 2 ]

3 голосов
/ 09 мая 2020

Использование модуля Python timeit для измерения различных альтернатив. Я добавил свой, который не преобразует ключи в список:

from timeit import timeit

dic = {str(i): i for i in range(10 ** 6)}

def f1():
    x = list(dic.keys())[0:30]
    return x

def f2():
    y = list(dic.keys())
    x = y[0:30]
    return x

def f3():
    z = dic.keys()
    y = list(z)
    x = y[0:30]
    return x

def f4():
    x = [k for _, k in zip(range(30), dic.keys())]
    return x

t1 = timeit(lambda: f1(), number=10)
t2 = timeit(lambda: f2(), number=10)
t3 = timeit(lambda: f3(), number=10)
t4 = timeit(lambda: f4(), number=10)

print(t1)
print(t2)
print(t3)
print(t4)

Печать:

0.1911074290110264
0.20418328599771485
0.18727918600779958
3.5186996683478355e-05
1 голос
/ 09 мая 2020

Может быть, это из-за неточностей в вашем измерении времени. Вы можете использовать timeit для таких действий:

import timeit

dic = {str(i): i for i in range(10 ** 6)}

# 27.5125/29.0836/26.8525
timeit.timeit("x = list(dic.keys())[0:30]", number=1000, globals={"dic": dic})

# 28.6648/26.4684/30.9534
timeit.timeit("y = list(dic.keys());x=y[0:30]", number=1000)

# 31.7345/29.5301/30.7541
timeit.timeit("z=dic.keys();y=list(z);x=y[0:30]", number=1000, globals={'dic': dic})

В комментариях показано, сколько раз я выполнял один и тот же код 3 раза. Как видите, даже выполняя большое количество повторений, можно получить довольно большие отклонения во времени. Это может быть связано с несколькими причинами:

  1. Элемент может быть в кеше вашего процессора или нет.
  2. Ваш процессор может быть занят другими делами.
  3. Et c ...

Как заявил @Andrej Kesely, ваше узкое место связано с тем, что вы помещаете ключи словаря в список. Таким образом, Python перебирает все ключи словаря, потому что именно так он обычно конвертирует что-то в list. Следовательно, избегая этого, вы можете получить гораздо лучшие результаты.

...