[pypy-dev] Copy of list

Oscar Benjamin oscar.j.benjamin at gmail.com
Mon Sep 28 19:21:33 CEST 2015


On Mon, 28 Sep 2015 at 14:57 Tuom Larsen <tuom.larsen at gmail.com> wrote:

> Dear PyPy developers!
>
> In CPython, a common idiom to copy a list is to use slice, as in:
>
>     copy = original[:]
>
> I noticed that under PyPy 2.6.0 it seems quite a bit slower than using
> `list` constructor:
>
>     from timeit import timeit
>     print timeit('b = a[:]', 'a = list(range(100))')    # 0.0732719898224
>     print timeit('b = list(a)', 'a = list(range(100))') # 0.00285792350769
>
> Please, could some comment on what is the preferred way to copy a list
> under PyPy? Should I try to avoid the "slice way"?
>

I don't get the same timings here:

enojb at it054759:~$ pypy -m timeit -s 'a = list(range(100))' 'b = a[:]'
1000000000 loops, best of 3: 0.00142 usec per loop
enojb at it054759:~$ pypy -m timeit -s 'a = list(range(100))' 'b = list(a)'
1000000000 loops, best of 3: 0.00109 usec per loop

So for me it's about the same. However if you look closer you'll see that
it's about 1 nanosecond in either case. That's really a very short time.
Why is so short? I guess because it's not really copying the lists. If I
try with a much bigger list it takes the same time:

enojb at it054759:~$ pypy -m timeit -s 'a = list(range(1000000))' 'b = a[:]'
1000000000 loops, best of 3: 0.00142 usec per loop
enojb at it054759:~$ pypy -m timeit -s 'a = list(range(1000000))' 'b =
list(a)'
1000000000 loops, best of 3: 0.00105 usec per loop

I would guess that the actual copy has somehow been optimised away. If I
make the expression do some actual work instead of just copying a list then
the differences are insignificant:

enojb at it054759:~$ pypy -m timeit -s 'a = list(range(100))' 'b = sum(a[:])'
1000000 loops, best of 3: 0.212 usec per loop
enojb at it054759:~$ pypy -m timeit -s 'a = list(range(100))' 'b =
sum(list(a))'
1000000 loops, best of 3: 0.205 usec per loop

So I wouldn't worry about how many nanoseconds the copy takes. Finish your
application and then if the difference between slice/list copy actually
affects whole application performance in a significant way then this
question may be worth considering.

Until then just code it whichever way seems clearest to you. Bear in mind
that the two are not equivalent since b[:] will return a tuple if b is a
tuple, or a range if b is a range etc.

--
Oscar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pypy-dev/attachments/20150928/42a22f6e/attachment.html>


More information about the pypy-dev mailing list