Why Numpy.array is slower than build-in list for fetching sub list
Question: I'm going to improve the performance of my code snippet which will frequently
getting sub-array recursively.

So I used numpy.array instead of build-in list. Because, as I know, when
fetching the sub-array, numpy.array don't copy the orginal list.

But when I changed to numpy.array, the performance got worse. So I want to
know the reason. Thanks!

Following is my code snippet and the execution times by using the different
objects I got:

    
    
    import timeit
    stat = ''' 
    import numpy
    def func(a):
        a[len(a)-1] += 1
        if len(a) == 1:
            return a[0]
        else:
            return func(a[1:len(a)])
    a1=[1,2,3,4,5,6,7,8,9,10]
    a2=numpy.array([1,2,3,4,5,6,7,8,9,10])
    '''
    if __name__ == "__main__":
        print "Execution time with build-in list: {0}".format(timeit.timeit('func(a1)', setup = stat, number = 1000))
        print "Execution time with Numpy array: {0}".format(timeit.timeit('func(a2)', setup = stat, number = 1000))
    

And on my 64-bit mac(Python 2.7.6 + Numpy 1.8.0rc1) the output is:

    
    
    Execution time with build-in list: 0.00507998466492
    Execution time with Numpy array: 0.0195469856262
    


Answer: You will get the same execution times if you modify your two last lines of
code as follows:

    
    
    print "Execution time with build-in list: {0}".format(timeit.timeit(
        'func(a1)', setup = stat, number = 1000), 'gc.enable()')
    print "Execution time with Numpy array:   {0}".format(timeit.timeit(
        'func(a2)', setup = stat, number = 1000), 'gc.enable()')
    

where in both cases we allowed _timeit_ to switch on so-called _garbage
collection_ , i.e. the process of freeing memory when it is not used anymore.
The abovementioned modification returns, e.g.:

    
    
    Execution time with build-in list: 0.00580596923828
    Execution time with Numpy array:   0.00822710990906
    

to be of the same order of magnitude. According to the documentation of
_timeit_ "by default, it temporarily turns off garbage collection during the
timing. The advantage of this approach is that it makes independent timings
more comparable. This disadvantage is that garbage collection may be an
important component of the performance of the function being measured."

There is a thin understanding what method, i.e. with or without garbage
collection, should be used and when. Please also note, that you will obtain
much longer times if you apply time.time() block from _time_ module.

