gpt4 book ai didi

Python str.translate VS str.替换

转载 作者:太空狗 更新时间:2023-10-29 20:37:53 25 4
gpt4 key购买 nike

为什么在 Python 中,replacetranslate 快 1.5 倍?

In [188]: s = '1 a  2'

In [189]: s.replace(' ','')
Out[189]: '1a2'

In [190]: s.translate(None,' ')
Out[190]: '1a2'

In [191]: %timeit s.replace(' ','')
1000000 loops, best of 3: 399 ns per loop

In [192]: %timeit s.translate(None,' ')
1000000 loops, best of 3: 614 ns per loop

最佳答案

假设使用 Python 2.7(因为我必须在没有说明的情况下掷硬币),我们可以找到 string.translate 的源代码和 string.replacestring.py 中:

>>> import inspect
>>> import string
>>> inspect.getsourcefile(string.translate)
'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/string.py'
>>> inspect.getsourcefile(string.replace)
'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/string.py'
>>>

哦,我们不能,as string.py 开头为:

"""A collection of string operations (most are no longer used).

Warning: most of the code you see here isn't normally used nowadays.
Beginning with Python 1.6, many of these functions are implemented as
methods on the standard string object.

我给你投了赞成票,因为你开始了分析的道路,所以让我们继续这个话题:

from cProfile import run
from string import ascii_letters

s = '1 a 2'

def _replace():
for x in range(5000000):
s.replace(' ', '')

def _translate():
for x in range(5000000):
s.translate(None, ' ')

用于替换:

run("_replace()")
5000004 function calls in 2.059 seconds

Ordered by: standard name

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.976 0.976 2.059 2.059 <ipython-input-3-9253b3223cde>:8(_replace)
1 0.000 0.000 2.059 2.059 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
5000000 1.033 0.000 1.033 0.000 {method 'replace' of 'str' objects}
1 0.050 0.050 0.050 0.050 {range}

和翻译:

run("_translate()")

5000004 function calls in 1.785 seconds

Ordered by: standard name

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.977 0.977 1.785 1.785 <ipython-input-3-9253b3223cde>:12(_translate)
1 0.000 0.000 1.785 1.785 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
5000000 0.756 0.000 0.756 0.000 {method 'translate' of 'str' objects}
1 0.052 0.052 0.052 0.052 {range}

我们的函数调用次数是一样的,并不是说更多的函数调用意味着运行会变慢,但它通常是一个值得一看的好地方。有趣的是,translate 在我的机器上比 replace 运行得更快!考虑到不单独测试变化的乐趣——这并不重要,因为我们只关心能够说出为什么可能会有所不同。

无论如何,我们至少现在知道可能存在性能差异,并且在评估字符串对象的方法时它确实存在(参见 tottime)。 translate __docstring__ 表明有一个翻译表在起作用,而 replace 只提到旧到新的子字符串替换。

求助老哥们dis提示:

from dis import dis

替换:

def dis_replace():
'1 a 2'.replace(' ', '')

dis(dis_replace)


dis("'1 a 2'.replace(' ', '')")

3 0 LOAD_CONST 1 ('1 a 2')
3 LOAD_ATTR 0 (replace)
6 LOAD_CONST 2 (' ')
9 LOAD_CONST 3 ('')
12 CALL_FUNCTION 2
15 POP_TOP
16 LOAD_CONST 0 (None)
19 RETURN_VALUE

translate,对我来说运行得更快:

def dis_translate():
'1 a 2'.translate(None, ' ')
dis(dis_translate)


2 0 LOAD_CONST 1 ('1 a 2')
3 LOAD_ATTR 0 (translate)
6 LOAD_CONST 0 (None)
9 LOAD_CONST 2 (' ')
12 CALL_FUNCTION 2
15 POP_TOP
16 LOAD_CONST 0 (None)
19 RETURN_VALUE

不幸的是,两者看起来与 dis 相同,这意味着我们应该从这里开始寻找字符串的 C 源代码(通过转到我正在使用的 Python 版本的 python 源代码找到现在)]( https://hg.python.org/cpython/file/a887ce8611d2/Objects/stringobject.c ).

这是 source for translate .
如果您查看注释,您会看到根据输入的长度,有多个 replace 函数定义行。

我们的子字符串替换选项是:

replace_substring_in_place

/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
Py_LOCAL(PyStringObject *)
replace_substring_in_place(PyStringObject *self,

replace_substring :

/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
Py_LOCAL(PyStringObject *)
replace_substring(PyStringObject *self,

replace_delete_single_character :

/* Special case for deleting a single character */
/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
Py_LOCAL(PyStringObject *)
replace_delete_single_character(PyStringObject *self,
char from_c, Py_ssize_t maxcount)

'1 a 2'.replace(' ', '')是一个len(self)==6,将1个字符替换为空字符串,使其成为replace_delete_single_character

您可以自己检查函数体,但答案是“C 函数体在 replace_delete_single_character 中运行速度比在 string_translate 中运行得更快。

感谢您提出这个问题。

关于Python str.translate VS str.替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31143290/

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