为什么在Python 3.5中与Python 3.4相比,str.translate更快?

问题:

我试图在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程序需要,而Python 3.5中的相同程序只需要
Python 3.5中有什么改进,使其比Python 3.4更快?

回答:

 TL; DR –
 漫长的故事
Josh Rosenberg发现str.translate()功能与bytes.translate相比非常慢,他提出了一个issue,指出:

在Python 3中,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之前,翻译用于ASCII和非ASCII情况下以相同的方式工作。但是从3.5 ASCII的情况来说要快得多。
以前的ASCII和非ascii以前几乎相同,但是现在我们可以看到性能有很大的变化。
可以从71.6μs到2.33μs的改善,如answer
以下代码演示了这一点

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

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Why is str.translate faster in Python 3.5 compared to Python 3.4?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

− 3 = 2