为什么用两条语句获取字典的前30个键比一条语句快?

问题描述 投票:0回答:1

我在给自己做基准的时候,遇到了这个有趣的事情。我想获取一个字典的前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

出乎意料的是,第二种方法要快得多! 对此有什么看法吗?

python-3.x benchmarking
1个回答
3
投票

使用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)

Prints:

0.1911074290110264
0.20418328599771485
0.18727918600779958
3.5186996683478355e-05

1
投票

也许是由于你对时间的测量不准确。你可以使用 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. 等等...

正如 @Andrej Kesely 所说的,你的瓶颈是由于你把你的字典键投进了一个列表。通过这样做,Python 会检查整个 dictionary keys,因为这就是它如何将某些东西转换为一个 list 一般来说,。因此,避免这种情况的发生,可以得到更好的效果。

© www.soinside.com 2019 - 2024. All rights reserved.