我试图在 Python 3.4 中使用 text.translate()
从给定字符串中删除不需要的字符。
最少的代码是:
import sys
s = 'abcde12345@#@$#%$'
mapper = dict.fromkeys(i for i in range(sys.maxunicode) if chr(i) in '@#$')
print(s.translate(mapper))
它按预期工作。然而,相同的程序在 Python 3.4 和 Python 3.5 中执行时会产生很大的差异。
计算时间的代码是
python3 -m timeit -s "import sys;s = 'abcde12345@#@$#%$'*1000 ; mapper = dict.fromkeys(i for i in range(sys.maxunicode) if chr(i) in '@#$'); " "s.translate(mapper)"
Python 3.4 程序需要 1.3ms,而 Python 3.5 中的相同程序只需要 26.4μs。
与 Python 3.4 相比,Python 3.5 的哪些改进使其更快?
最佳答案
TL;DR - ISSUE 21118
长篇大论
Josh Rosenberg 发现 str.translate()
函数与 bytes.translate
相比非常慢,他提出了 issue ,声明:
In Python 3,
str.translate()
is usually a performance pessimization, not optimization.
为什么 str.translate()
很慢?
str.translate()
非常慢的主要原因是查找曾经在 Python 字典中。
maketrans
的使用使这个问题变得更糟。使用 bytes
的类似方法构建一个包含 256 个项目的 C 数组以快速查找表。因此使用更高级别的 Python dict
使得 Python 3.4 中的 str.translate()
非常慢。
现在发生了什么?
第一种方法是添加一个小补丁 translate_writer , 但是速度的提升并不是那么令人愉快。很快另一个补丁fast_translate经过测试,它产生了高达 55% 加速的非常好的结果。
从文件中可以看出主要的变化是Python字典查找变成了C级查找。
现在的速度几乎和bytes
unpatched patched
str.translate 4.55125927699919 0.7898181750006188
str.translate from bytes trans 1.8910855210015143 0.779950579000797
这里需要注意的是,性能增强仅在 ASCII 字符串中突出。
正如 J.F.Sebastian 在 comment 中提到的那样下面,在 3.5 之前,translate 在 ASCII 和非 ASCII 情况下的工作方式相同。但是从 3.5 ASCII 大小写开始要快得多。
早期的 ASCII 与非 ASCII 过去几乎相同,但现在我们可以看到性能上有很大的变化。
如 answer 所示,它可以从 71.6μs 提高到 2.33μs .
以下代码演示了这一点
python3.5 -m timeit -s "text = 'mJssissippi'*100; d=dict(J='i')" "text.translate(d)"
100000 loops, best of 3: 2.3 usec per loop
python3.5 -m timeit -s "text = 'm\U0001F602ssissippi'*100; d={'\U0001F602': 'i'}" "text.translate(d)"
10000 loops, best of 3: 117 usec per loop
python3 -m timeit -s "text = 'm\U0001F602ssissippi'*100; d={'\U0001F602': 'i'}" "text.translate(d)"
10000 loops, best of 3: 91.2 usec per loop
python3 -m timeit -s "text = 'mJssissippi'*100; d=dict(J='i')" "text.translate(d)"
10000 loops, best of 3: 101 usec per loop
结果列表:
Python 3.4 Python 3.5
Ascii 91.2 2.3
Unicode 101 117
关于python - 为什么 Python 3.5 中的 str.translate 比 Python 3.4 快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34287893/