het*_*fan 2 python performance list-comprehension augmented-assignment
今天我试图找到一个方法,在python中对字符串进行一些处理.一些比我说的高级程序员不使用+=但使用''.join()我也可以在例如http://wiki.python.org/moin/PythonSpeed/#Use_the_best_algorithms_and_fastest_tools中阅读.但是我自己测试了这个并且发现了一些奇怪的结果(这不是我想要再猜测它们但是我想要站立).想法是,如果有一个"This is \"an example text\"包含空格的字符串"字符串应该被转换为Thisis"an example text"containingspaces空格被删除,但只在引号之外.
我测量了我的算法的两个不同版本的性能,使用了''.join(list)一个和一个+=
import time
#uses '+=' operator
def strip_spaces ( s ):
ret_val = ""
quote_found = False
for i in s:
if i == '"':
quote_found = not quote_found
if i == ' ' and quote_found == True:
ret_val += i
if i != ' ':
ret_val += i
return ret_val
#uses "".join ()
def strip_spaces_join ( s ):
#ret_val = ""
ret_val = []
quote_found = False
for i in s:
if i == '"':
quote_found = not quote_found
if i == ' ' and quote_found == True:
#ret_val = ''.join( (ret_val, i) )
ret_val.append(i)
if i != ' ':
#ret_val = ''.join( (ret_val,i) )
ret_val.append(i)
return ''.join(ret_val)
def time_function ( function, data):
time1 = time.time();
function(data)
time2 = time.time()
print "it took about {0} seconds".format(time2-time1)
Run Code Online (Sandbox Code Playgroud)
在我的机器上,这产生了这个输出,对于算法使用有一个小优势 +=
print '#using += yields ', timeit.timeit('f(string)', 'from __main__ import string, strip_spaces as f', number=1000)
print '#using \'\'.join() yields ', timeit.timeit('f(string)', 'from __main__ import string, strip_spaces_join as f', number=1000)
Run Code Online (Sandbox Code Playgroud)
与timeit计时时:
#using += yields 0.0130770206451
#using ''.join() yields 0.0108470916748
Run Code Online (Sandbox Code Playgroud)
差别很小.但是为什么''.join()没有明确地执行使用的功能+=,但是'.join()版本似乎有一个小优势.我使用python-2.7.3在Ubuntu 12.04上测试了这个
比较算法时,请使用正确的方法; 使用该timeit模块消除CPU利用率和交换的波动.
用timeit节目有两种方法之间的差别不大,但是''.join()是稍快:
>>> s = 1000 * string
>>> timeit.timeit('f(s)', 'from __main__ import s, strip_spaces as f', number=100)
1.3209099769592285
>>> timeit.timeit('f(s)', 'from __main__ import s, strip_spaces_join as f', number=100)
1.2893600463867188
>>> s = 10000 * string
>>> timeit.timeit('f(s)', 'from __main__ import s, strip_spaces as f', number=100)
14.545105934143066
>>> timeit.timeit('f(s)', 'from __main__ import s, strip_spaces_join as f', number=100)
14.43651008605957
Run Code Online (Sandbox Code Playgroud)
函数中的大部分工作是循环遍历每个字符并测试引号和空格,而不是字符串连接本身.此外,该''.join()变体做了更多的工作; 您首先将元素附加到列表中(这将替换+=字符串连接操作),然后使用结束时将这些值连接起来''.join().而且这种方法仍然有点快.
您可能想要删除正在进行的工作以仅比较连接部分:
def inplace_add_concatenation(s):
res = ''
for c in s:
res += c
def str_join_concatenation(s):
''.join(s)
Run Code Online (Sandbox Code Playgroud)
这表现了:
>>> s = list(1000 * string)
>>> timeit.timeit('f(s)', 'from __main__ import s, inplace_add_concatenation as f', number=1000)
6.113742113113403
>>> timeit.timeit('f(s)', 'from __main__ import s, str_join_concatenation as f', number=1000)
0.6616439819335938
Run Code Online (Sandbox Code Playgroud)
这表明''.join()串联仍然是一个赫克了很多的速度比+=.速度差异在于循环; s在这两种情况下都是一个列表,但是''.join()循环遍历C中的值,而另一个版本必须在Python中循环它.这在这里有所不同.