Why indexing list is slower than allocating a new list?

Viewed 46

I thought that indexing a list would be much faster than additional memory allocations. However, the code below results in a quite surprising results.

import random, timeit
from scipy import stats

random.seed(42)
a = [random.randint(-10000, 10000) for _ in range(10000)]

def new_list(a):
    b = []
    for v in a:
        b.append(v*2)

def in_place(a):
    for i in range(len(a)):
        a[i] *= 2

print(stats.describe(timeit.repeat("new_list(a_cp)", setup="a_cp = a.copy()",
                                    number=100, globals=globals())))
print(stats.describe(timeit.repeat("in_place(a_cp)", setup="a_cp = a.copy()",
                                    number=100, globals=globals())))

The result I got is

DescribeResult(nobs=5, minmax=(0.16783145900000007, 0.2041749690000001), mean=0.18718994520000004, variance=0.00018897353500515855, skewness=-0.23156148623021452, kurtosis=-1.0041025476826309)
DescribeResult(nobs=5, minmax=(0.25297652999999976, 0.2932831710000001), mean=0.2716082258, variance=0.00024360213447797058, skewness=0.2423908282124137, kurtosis=-1.136485780718656)

It is quite a difference, isn't it? Even though I'd rather use numpy if performance really matters, I could not get a good reason why allocating new memory is faster than traveling through pointers. Could anyone help me?

Edit:: As my question is bit unclear, I changed the title and removed some sentences.

1 Answers

It is not mutating the list that is slow but indexing it. If you change the new_list function to employ indexing as well the latter will be faster:

def new_list(a):
    b = []
    for i in range(len(a)):
        b.append(a[i] * 2)
Related