gpt4 book ai didi

python - 使用 set literals 更快地设置包含

转载 作者:行者123 更新时间:2023-12-05 01:27:12 25 4
gpt4 key购买 nike

在下面我用 10_000_000 检查 10 是否在 {0, ..., 9} 中。

在第一个检查中我使用了一个中间变量,在第二个检查中我使用了一个文字。

import timeit

x = 10
s = set(range(x))
number = 10 ** 7

stmt = f'my_set = {s} ; {x} in my_set'
print(f'eval "{stmt}"')
print(timeit.timeit(stmt=stmt, number=number))

stmt = f'{x} in {s}'
print(f'eval "{stmt}"')
print(timeit.timeit(stmt=stmt, number=number))

输出:

eval "my_set = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ; 10 in my_set"
1.2576093
eval "10 in {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}"
0.20336140000000036

为什么第二个更快(大约快 5-6 倍)? Python 是否执行了一些运行时优化,例如,如果包含检查是否在文字上进行?或者可能是由于垃圾收集(因为它是文字 python 垃圾在使用后立即收集它)?

最佳答案

您没有测试相同的两件事——在第一个测试中,除了成员测试之外,您还对两个分配和查找进行了计时:

In [1]: import dis
...: x = 10
...: s = set(range(x))

In [2]: dis.dis("x in s")
1 0 LOAD_NAME 0 (x)
2 LOAD_NAME 1 (s)
4 CONTAINS_OP 0
6 RETURN_VALUE

In [3]: dis.dis("my_set = s; x in my_set")
1 0 LOAD_NAME 0 (s)
2 STORE_NAME 1 (my_set)
4 LOAD_NAME 2 (x)
6 LOAD_NAME 1 (my_set)
8 CONTAINS_OP 0
10 POP_TOP
12 LOAD_CONST 0 (None)
14 RETURN_VALUE

# By request
In [4]: dis.dis("s = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 10 in s")
1 0 BUILD_SET 0
2 LOAD_CONST 0 (frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}))
4 SET_UPDATE 1
6 STORE_NAME 0 (s)
8 LOAD_CONST 1 (10)
10 LOAD_NAME 0 (s)
12 CONTAINS_OP 0
14 POP_TOP
16 LOAD_CONST 2 (None)
18 RETURN_VALUE

使用文字和 x in s 之间的实际区别是后者需要在全局变量中执行查找,即区别是 LOAD_NAME 对比 LOAD_CONST:

In [5]: dis.dis("10 in {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}")
1 0 LOAD_CONST 0 (10)
2 LOAD_CONST 1 (frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}))
4 CONTAINS_OP 0
6 RETURN_VALUE

时间:

In [6]: %timeit x in s
28.5 ns ± 0.792 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [7]: %timeit 10 in {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
20.3 ns ± 0.384 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

关于python - 使用 set literals 更快地设置包含,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69650210/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com