
On Mon, 28 Sep 2015 at 14:57 Tuom Larsen <tuom.larsen@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@it054759:~$ pypy -m timeit -s 'a = list(range(100))' 'b = a[:]' 1000000000 loops, best of 3: 0.00142 usec per loop enojb@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@it054759:~$ pypy -m timeit -s 'a = list(range(1000000))' 'b = a[:]' 1000000000 loops, best of 3: 0.00142 usec per loop enojb@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@it054759:~$ pypy -m timeit -s 'a = list(range(100))' 'b = sum(a[:])' 1000000 loops, best of 3: 0.212 usec per loop enojb@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