For comparison, PHP has mutable strings. Some totally unscientific averaged benchmarks (Atom D2700, PHP 5.4.4-14 amd64): $buff = ''; for ($i = 0; $i != 100000; ++$i) { $buff .= $i; } Runs in about 0.06s $buff = array(); for ($i = 0; $i != 100000; ++$i) { $buff[] = $i; } $ret = implode('', $buff); Runs slower, in about 0.10s $ret = implode('', range(0, 100000)); Takes roughly the same time, 0.10s
Efficient String Concatenation in Python
21–29 of 29 posts
Re: Efficient String Concatenation in Python
#22Re: Efficient String Concatenation in Python
#23Earlier quoted context omitted.
Does PyPy have the same heuristic? If not, I wouldn't recommend relying on it.
If not, I would recommend submitting a bug to PyPy.
"We have it, just not enabled by default. --objspace-with-strbuf I think" [1]
[1] https://mail.python.org/pipermail/python-dev/2013-February/1...
Re: Efficient String Concatenation in Python
#24Note that since this article was written (2004) CPython performs an in-place optimisation for assignments of the form s1 += s2 There are details at point six of http://docs.python.org/2/library/stdtypes.html#sequence-type... , where it also says that str.join() is preferable.
Method 1: 0.115 seconds
Method 2: I gave up after >120s
Method 3: 0.265
Method 4: 0.160
Method 5: 0.220
Method 6: 0.098
I ran each one a few times to make sure the times were roughly correct. Method 6 is still the fastest, but the naive method one is really close. it obviously got optimized. Actually, they're all pretty close with the obvious (and hideous) outlier of using MutableString.EDIT:
I just remembered I have an old version of PyPy (1.8) on my Mac. Thought I'd give that a try.
Method 1: I gave up after >120s
Method 2: I gave up after >120s
Method 3: 0.090 seconds
Method 4: 0.102
Method 5: 0.430
Method 6: 0.102
Method one is a problem again, and method 5 (the pseudo file) is noticeably slower. Otherwise the results aren't too far off.Re: Efficient String Concatenation in Python
#25I believe that the current most efficient way of doing this is ''.join(map(str, range(n)))
In Python 2, itertools.imap will be faster since it doesn't realize a list. Also, if you are memory constrained, xrange doesn't realize a list either, whereas range does (but the article notes that range was slightly faster than xrange in his tests--I don't know if that's still true in Python 2, the article is 9 years old). In Python 3, the map builtin is basically equivalent what itertools.imap was in Python 2, so i…
(Here I'm using the stock Python 2.7.1 on a 2011 MacBook Pro.)
Re: Efficient String Concatenation in Python
#26Re: Efficient String Concatenation in Python
#27Note that since this article was written (2004) CPython performs an in-place optimisation for assignments of the form s1 += s2 There are details at point six of http://docs.python.org/2/library/stdtypes.html#sequence-type... , where it also says that str.join() is preferable.
OK, so for fun I did a ran this on my machine (MacBook Pro, 2.53GHz, 10.8.4, 8GB ram, Python 2.7.2 shipped by Apple). I had to emulate the old timing module using code from [1]. Method 1: 0.115 seconds Method 2: I gave up after >120s Method 3: 0.265 Method 4: 0.160 Method 5: 0.220 Method 6: 0.098 I ran each one a few times to make sure the times were roughly correct. Method 6 is still the fastest, but the naive metho…
for 10M loop count, method 1 -> 1.599 s, method 6 -> 1.91 s
for 30M loop count,method 1 -> 4.967 s, method 6 -> 5.871 s
Summary: The KISS s1 += s2 always wins
Re: Efficient String Concatenation in Python
#28I did many kind of performance tests when implementing my PyClockPro caching lib, even if I don't use strings in it.
Re: Efficient String Concatenation in Python
#29Earlier quoted context omitted.
In Python 2, itertools.imap will be faster since it doesn't realize a list. Also, if you are memory constrained, xrange doesn't realize a list either, whereas range does (but the article notes that range was slightly faster than xrange in his tests--I don't know if that's still true in Python 2, the article is 9 years old). In Python 3, the map builtin is basically equivalent what itertools.imap was in Python 2, so i…
I tried it with n=1000 and n=10000, and found that using xrange made it slightly faster, as did using itertools.imap, but the difference was pretty small. (Here I'm using the stock Python 2.7.1 on a 2011 MacBook Pro.)
That's what I would expect, since xrange works like a generator; but the internals of its implementation in CPython back when the article ran its original tests were evidently less efficient than they are now.
the difference was pretty small
I suspect that's because the strings being concatenated are really small (the largest will only be 5 bytes for n=10000). I would expect the difference to get bigger as the individual strings get larger.