title: Performance in different vectorization method in numpy
body: <p>I wanted to test the performance of vectorizing code in python:</p>
  
  <pre><code>import timeit
  import numpy as np
  
  def func1():
    x = np.arange(1000)
    sum = np.sum(x*2)
    return sum
  
  def func2():
    sum = 0
    for i in xrange(1000):
      sum += i*2
    return sum
  
  def func3():
    sum = 0
    for i in xrange(0,1000,4):
      x = np.arange(i,i+4,1)
      sum += np.sum(x*2)
    return sum
  
  print timeit.timeit(func1, number = 1000)
  print timeit.timeit(func2, number = 1000)
  print timeit.timeit(func3, number = 1000)
  </code></pre>
  
  <p>The code gives the following output:</p>
  
  <pre><code>0.0105729103088
  0.069864988327
  0.983253955841
  </code></pre>
  
  <p>The performance difference in the first and second functions are not surprising. But I was surprised that the 3rd function is significantly slower than the other functions. </p>
  
  <p>I am much more familiar in vectorising code in C than in Python and the 3rd function is more C-like - running a for loop and processing 4 numbers in one instruction in each loop. To my understanding numpy calls a C function and then vectorize the code in C. So if this is the case my code is also passing 4 numbers to numpy each at a time. The code shouldn't perform better when I pass more numbers at once. So why is it much more slower? Is it because of the overhead in calling a numpy function?</p>
  
  <p>Besides, the reason that I even came up with the 3rd function in the first place is because I'm worried about the performance of the large amount of memory allocation to <code>x</code> in <code>func1</code>. </p>
  
  <p>Is my worry valid? Why and how can I improve it or why not? </p>
  
  <p>Thanks in advance. </p>
  
  <p>Edit: </p>
  
  <p>For curiosity sake, although it defeats my original purpose for creating the 3rd version, I have looked into roganjosh's suggestion and tried the following edit.</p>
  
  <pre><code>def func3():
    sum = 0
    x = np.arange(0,1000)
    for i in xrange(0,1000,4):
      sum += np.sum(x[i:i+4]*2)
    return sum
  </code></pre>
  
  <p>The output:</p>
  
  <pre><code>0.0104308128357
  0.0630609989166
  0.748773813248
  </code></pre>
  
  <p>There is an improvement, but still a large gap compared with the other functions.</p>
  
  <p>Is it because <code>x[i:i+4]</code> still creates a new array?   </p>
  
  <p>Edit 2:</p>
  
  <p>I've modified the code again according to Daniel's suggestion.</p>
  
  <pre><code>def func1():
    x = np.arange(1000)
    x *= 2
    return x.sum()
  
  def func3():
    sum = 0
    x = np.arange(0,1000)
    for i in xrange(0,1000,4):
      x[i:i+4] *= 2
      sum += x[i:i+4].sum()
    return sum
  </code></pre>
  
  <p>The output:</p>
  
  <pre><code>0.00824999809265
  0.0660569667816
  0.598328828812
  </code></pre>
  
  <p>There is another speedup. So the declaration of numpy arrays are definitely a problem.Now in func3 there should be one array declaration only, but yet the time is still way slower. Is it because of the overhead of calling numpy arrays?</p>