Possible memory leak?

Giovanni Bajo raNOsky at deveSPAMler.com
Wed Jan 25 14:08:56 EST 2006


Steven D'Aprano wrote:

> No, that's not correct. You are making a false
> assumption.

Did you ever try to measure the code yourself?

> This is from the "What's New" for Python 2.4:
>
> [quote]
> String concatenations in statements of the form s = s +
> "abc" and s += "abc" are now performed more efficiently
> in certain circumstances. This optimization won't be
> present in other Python implementations such as Jython,
> so you shouldn't rely on it; using the join() method of
> strings is still recommended when you want to
> efficiently glue a large number of strings together.
> [end quote]
>
> Note the "more efficiently in CERTAIN CIRCUMSTANCES"
> [emphasis added]? That certainly does not mean that
> concatenating large numbers of strings is no longer
> slow. It just means that *sometimes* (almost always?
> often? occasionally?) it isn't as slow as it used to be.
>
> We really don't know what the optimization recognises,
> how it works, or how fast a difference it makes.
> Writing poor code, and trusting an implementation-
> specific optimization to make it run "faster" (how much
> faster?) is always a dangerous strategy.

The code is poor by your definition of poor. In my definition, it used to be
poor and it's not anymore. Since I was interested in exactly WHICH
circumstances the optimization was performed, I investigated and I know the
answer. I also know that the optimization *will* apply to the OP code. But
maybe you want some numbers:

------- foo.py -----
def iters(n):
    s = ''
    for i in xrange(n):
        s += chr(i%64)
    return s

def iters2(n):
    L = []
    for i in xrange(n):
        L.append(chr(i%64))
    return "".join(L)
------- foo.py -----

[D:\Work]python -m timeit -n100 -s "import foo" "foo.iters(10000)"
100 loops, best of 3: 10.2 msec per loop

[D:\Work]python -m timeit -n100 -s "import foo" "foo.iters(20000)"
100 loops, best of 3: 20.5 msec per loop

[D:\Work]python -m timeit -n100 -s "import foo" "foo.iters(40000)"
100 loops, best of 3: 40.9 msec per loop

[D:\Work]python -m timeit -n100 -s "import foo" "foo.iters(80000)"
100 loops, best of 3: 81.6 msec per loop



[D:\Work]python -m timeit -n100 -s "import foo" "foo.iters2(10000)"
100 loops, best of 3: 10.9 msec per loop

[D:\Work]python -m timeit -n100 -s "import foo" "foo.iters2(20000)"
100 loops, best of 3: 22.2 msec per loop

[D:\Work]python -m timeit -n100 -s "import foo" "foo.iters2(40000)"
100 loops, best of 3: 44 msec per loop

[D:\Work]python -m timeit -n100 -s "import foo" "foo.iters2(80000)"
100 loops, best of 3: 89.9 msec per loop


So, look, it's even faster than the solution you're proposing.
-- 
Giovanni Bajo





More information about the Python-list mailing list