为什么使用“in”运算符检查可打印字节比使用间隔比较更快?

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

我试图弄清楚“in”运算符为何比检查值是否在某些间隔范围内提供更好的性能。

为什么第一段代码比第二段慢?直觉上我预计第一段代码会更快(3 个布尔运算 + 4 个整数比较),因为它只检查每个字节的每个间隔的边界,而第二个代码将迭代我们的字符集的整个数组(比较针对长度=100 的数组中的每个整数)。

import random

data = random.randbytes(1000000)
a_lower, a_upper, b_lower, b_upper = (9, 13, 32, 126)
%timeit [((x >= a_lower and x <= a_upper) or (x >= b_lower and x <= b_upper)) for x in data]

结果约为 82 毫秒

import string
import random

data = random.randbytes(1000000)
charset = bytearray(string.printable, "ascii")
%timeit [x in charset for x in data]

结果约为 44 毫秒

我研究了 bytesarray“in”的 CPython 实现,看起来它最终到达了 memchr

我剩下的唯一理论是,第二段代码中可能有更多的函数调用,最终占用的 CPU 时间比“基本操作”数量之间的差异还要多。

python time-complexity computer-science
1个回答
0
投票

我认为这是因为第二个解决方案可以使用

memchr
,它是纯C,因此比第一个解决方案中的Python比较快得多。如果您通过 numpy 执行第一个解决方案,您甚至比第二个解决方案更快(在我的机器上大约 100 倍):

import random
import numpy as np

data = random.randbytes(1000000)
a_lower, a_upper, b_lower, b_upper = (9, 13, 32, 126)
data = np.frombuffer(data, dtype=np.uint8)
%timeit ((data >= a_lower) & (data <= a_upper)) | ((data >= b_lower) & (data <= b_upper))
© www.soinside.com 2019 - 2024. All rights reserved.