Python相当于Java StringBuffer吗? [英] Python equivalent of Java StringBuffer?
问题描述
Python中是否有像Java的StringBuffer
一样的东西?由于字符串在Python中也是不可变的,因此在循环中对其进行编辑将效率很低.
Is there anything in Python like Java's StringBuffer
? Since strings are immutable in Python too, editing them in loops would be inefficient.
推荐答案
Python中的高效字符串连接是一篇比较老的文章,其主要声明天真的连接比连接慢得多,这不再有效,因为从那时起,该部分已在CPython中进行了优化:
Efficient String Concatenation in Python is a rather old article and its main statement that the naive concatenation is far slower than joining is not valid anymore, because this part has been optimized in CPython since then:
CPython实现细节:如果s和t都是字符串,则某些Python实现(例如CPython)通常可以对s = s + t或s + = t形式的赋值执行就地优化.如果适用,此优化将使二次运行的可能性大大降低.此优化取决于版本和实现.对于性能敏感的代码,最好使用str.join()方法,以确保跨版本和实现的一致线性连接性能. @ http://docs.python.org/2/library/stdtypes.html
我已经稍微修改了他们的代码,并在我的机器上得到了以下结果:
I've adapted their code a bit and got the following results on my machine:
from cStringIO import StringIO
from UserString import MutableString
from array import array
import sys, timeit
def method1():
out_str = ''
for num in xrange(loop_count):
out_str += `num`
return out_str
def method2():
out_str = MutableString()
for num in xrange(loop_count):
out_str += `num`
return out_str
def method3():
char_array = array('c')
for num in xrange(loop_count):
char_array.fromstring(`num`)
return char_array.tostring()
def method4():
str_list = []
for num in xrange(loop_count):
str_list.append(`num`)
out_str = ''.join(str_list)
return out_str
def method5():
file_str = StringIO()
for num in xrange(loop_count):
file_str.write(`num`)
out_str = file_str.getvalue()
return out_str
def method6():
out_str = ''.join([`num` for num in xrange(loop_count)])
return out_str
def method7():
out_str = ''.join(`num` for num in xrange(loop_count))
return out_str
loop_count = 80000
print sys.version
print 'method1=', timeit.timeit(method1, number=10)
print 'method2=', timeit.timeit(method2, number=10)
print 'method3=', timeit.timeit(method3, number=10)
print 'method4=', timeit.timeit(method4, number=10)
print 'method5=', timeit.timeit(method5, number=10)
print 'method6=', timeit.timeit(method6, number=10)
print 'method7=', timeit.timeit(method7, number=10)
结果:
2.7.1 (r271:86832, Jul 31 2011, 19:30:53)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)]
method1= 0.171155929565
method2= 16.7158739567
method3= 0.420584917068
method4= 0.231794118881
method5= 0.323612928391
method6= 0.120429992676
method7= 0.145267963409
结论:
-
join
仍然击败concat,但微弱 - 列表理解比循环快(构建时,列表)
- 加入生成器比加入列表慢
- 其他方法没有用(除非您正在做一些特殊的事情)
join
still wins over concat, but marginally- list comprehensions are faster than loops (when building a list)
- joining generators is slower than joining lists
- other methods are of no use (unless you're doing something special)
import sys
import timeit
from io import StringIO
from array import array
def test_concat():
out_str = ''
for _ in range(loop_count):
out_str += 'abc'
return out_str
def test_join_list_loop():
str_list = []
for _ in range(loop_count):
str_list.append('abc')
return ''.join(str_list)
def test_array():
char_array = array('b')
for _ in range(loop_count):
char_array.frombytes(b'abc')
return str(char_array.tostring())
def test_string_io():
file_str = StringIO()
for _ in range(loop_count):
file_str.write('abc')
return file_str.getvalue()
def test_join_list_compr():
return ''.join(['abc' for _ in range(loop_count)])
def test_join_gen_compr():
return ''.join('abc' for _ in range(loop_count))
loop_count = 80000
print(sys.version)
res = {}
for k, v in dict(globals()).items():
if k.startswith('test_'):
res[k] = timeit.timeit(v, number=10)
for k, v in sorted(res.items(), key=lambda x: x[1]):
print('{:.5f} {}'.format(v, k))
结果
3.7.5 (default, Nov 1 2019, 02:16:32)
[Clang 11.0.0 (clang-1100.0.33.8)]
0.03738 test_join_list_compr
0.05681 test_join_gen_compr
0.09425 test_string_io
0.09636 test_join_list_loop
0.11976 test_concat
0.19267 test_array
这篇关于Python相当于Java StringBuffer吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!