best way to replace first word in string?

Mike Meyer mwm at mired.org
Sat Oct 22 14:54:24 EDT 2005


Steven D'Aprano <steve at REMOVETHIScyber.com.au> writes:
> py> def tester(n):
> ...     s1 = ""
> ...     s2 = "%s" * n
> ...     bytes = tuple([chr(i % 256) for i in range(n)])
> ...     t1 = time.time()
> ...     for i in range(n):
> ...             s1 = s1 + chr(i % 256)
> ...     t1 = time.time() - t1
> ...     t2 = time.time()
> ...     s2 = s2 % bytes
> ...     t2 = time.time() - t2
> ...     assert s1 == s2
> ...     print t1, t2
> ...
> py> 
> py> tester(x)
> 3.24212408066 0.01252317428
> py> tester(x)
> 2.58376598358 0.01238489151
> py> tester(x)
> 2.76262307167 0.01474809646
>
> The string formatting is two orders of magnitude faster than the
> concatenation. The speed difference becomes even more obvious when you
> increase the number of strings being concatenated:

The test isn't right - the addition test case includes the time to
convert the number into a char, including taking a modulo.

I couldn't resist adding the .join idiom to this test:

>>> def tester(n):
...  l1 = [chr(i % 256) for i in range(n)]
...  s1 = ""
...  t1 = time.time()
...  for c in l1:
...   s1 += c
...  t1 = time.time() - t1
...  s2 = '%s' * n
...  l2 = tuple(chr(i % 256) for i in range(n))
...  t2 = time.time()
...  s2 = s2 % l2
...  t2 = time.time() - t2
...  t3 = time.time()
...  s3 = ''.join(l2)
...  t3 = time.time() - t3
...  assert s1 == s2
...  assert s1 == s3
...  print t1, t2, t3
... 
>>> tester(x)
0.0551731586456 0.0251281261444 0.0264830589294
>>> tester(x)
0.0585241317749 0.0239250659943 0.0256059169769
>>> tester(x)
0.0544500350952 0.0271301269531 0.0232360363007

The "order of magnitude" now falls to a factor of two. The original
version of the test on my box also showed an order of magnitude
difference, so this isn't an implementation difference.

This version still includes the overhead of the for loop in the test.

The join idiom isn't enough faster to make a difference.

> py> tester(x*10)
> 2888.56399703 0.13130998611

>>> tester(x * 10)
1.22272014618 0.252701997757 0.27273607254
>>> tester(x * 10)
1.21779584885 0.255345106125 0.242965936661
>>> tester(x * 10)
1.25092792511 0.311630964279 0.241738080978
>>> 

Here we get the addition idiom being closer to a factor of four
instead of two slower. The .joim idiom is still nearly identical.

        <mike
-- 
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.



More information about the Python-list mailing list