title: Where are the gains using numba coming from for pure numpy code?
body: <p>I would like to understand where the gains are coming from when using Numba to accelerate pure <code>numpy</code> code in a for loop. Are there any profiling tools that allow you to look into <code>jitted</code> functions? </p>
  
  <p>The demo code (as below) is just using very basic matrix multiplication to provide work to the computer. Are the observed gains from:</p>
  
  <ol>
  <li>a faster <code>loop</code>,</li>
  <li>the recasting of <code>numpy</code> functions intercepted by the <code>jit</code> during the compilation process, or</li>
  <li>less overhead with <code>jit</code> as numpy outsources execution via wrapper functions to low level libraries such as <code>LINPACK</code></li>
  </ol>
  
  
  
  <pre class="lang-py prettyprint-override"><code>%matplotlib inline
  import numpy as np
  from numba import jit
  import pandas as pd
  
  #Dimensions of Matrices
  i = 100 
  j = 100
  
  def pure_python(N,i,j):
      for n in range(N):
          a = np.random.rand(i,j)
          b = np.random.rand(i,j)
          c = np.dot(a,b)
  
  @jit(nopython=True)
  def jit_python(N,i,j):
      for n in range(N):
          a = np.random.rand(i,j)
          b = np.random.rand(i,j)
          c = np.dot(a,b)
  
  time_python = []
  time_jit = []
  N = [1,10,100,500,1000,2000]
  for n in N:
      time = %timeit -oq pure_python(n,i,j)
      time_python.append(time.average)
      time = %timeit -oq jit_python(n,i,j)
      time_jit.append(time.average)
  
  df = pd.DataFrame({'pure_python' : time_python, 'jit_python' : time_jit}, index=N)
  df.index.name = 'Iterations'
  df[["pure_python", "jit_python"]].plot()
  </code></pre>
  
  <p>produces the following chart.</p>
  
  <p><a href="https://i.stack.imgur.com/9FRBo.png" rel="noreferrer"><img src="https://i.stack.imgur.com/9FRBo.png" alt="runtime comparisons for a range of iteration lengths"></a></p>