当前位置:  开发笔记 > 编程语言 > 正文

与Python 3.4相比,为什么Python 3.5中的str.translate要快得多?

如何解决《与Python3.4相比,为什么Python3.5中的str.translate要快得多?》经验,为你挑选了1个好方法。

我试图text.translate()在Python 3.4中删除给定字符串中不需要的字符.

最小的代码是:

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.3毫秒,而Python 3.5中的相同程序只需要26.4μs.

与Python 3.4相比,Python 3.5有哪些改进使其更快?



1> Bhargav Rao..:

TL; DR - ISSUE 21118


漫长的故事

乔什罗森伯格发现这个str.translate()功能非常缓慢bytes.translate,他提出了一个问题,并指出:

在Python 3中,str.translate()通常是性能悲观,而不是优化.

为什么str.translate()慢?

str.translate()非常慢的主要原因是查找曾经在Python字典中.

使用maketrans使这个问题变得更糟.类似的方法使用bytes构建256个项目的C数组来快速查找表.因此,使用更高级别的Python dict会使str.translate()Python 3.4非常慢.

现在发生什么事?

第一种方法是添加一个小补丁,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字符串中很突出.

正如JFSebastian在下面的评论中提到的,在3.5之前,翻译曾经以相同的方式用于ASCII和非ASCII情况.但是从3.5 ASCII情况下要快得多.

早期的ASCII与非ascii过去几乎相同,但现在我们可以看到性能的巨大变化.

如本答案所示,它可以从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


这是提交之一:https://github.com/python/cpython/commit/87056cb061ede3c30952c43970b41cafa112d3bf
推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有