2

I'm trying to compare numba and pure python using the basic example and I'm getting odd results.

This is the numba example:

from numba import jit
from numpy import arange
from time import time
# jit decorator tells Numba to compile this function.
# The argument types will be inferred by Numba when function is called.
@jit
def sum2d(arr):
    M, N = arr.shape
    result = 0.0
    for i in range(M):
        for j in range(N):
            result += arr[i,j]
    return result

a = arange(9).reshape(3,3)
t = time()
print(sum2d(a))
print time() - t

This is the timing I'm getting with numba 0.0469660758972 seconds

And without numba I'm getting a faster result 9.60826873779e-05 seconds

msgb
  • 23
  • 4
  • It's a very small example. How do you timed it? – terence hill Feb 10 '17 at 17:12
  • @terencehill Thanks for quick reply. I edited my original post – msgb Feb 10 '17 at 17:17
  • 1
    You're probably spending most of the time compiling – user357269 Feb 10 '17 at 17:20
  • You're timing one execution of the function. You're not going to see the JIT benefits if you only execute it once; you're only going to see the overhead. – user2357112 Feb 10 '17 at 17:20
  • Try a larger example, remove the print from the timing and, which is the resolution of the time() function? See this post for better timing functions http://stackoverflow.com/questions/7370801/measure-time-elapsed-in-python – terence hill Feb 10 '17 at 17:21
  • I understand what are you referring but this is the basic example from the main webpage: http://numba.pydata.org/ – msgb Feb 10 '17 at 17:24
  • @user357269 it is correct to call the function twice and timing only the second call? The compilation should be done only once isn't it? – terence hill Feb 10 '17 at 17:24
  • In the main page they don't say that this example show the gain in performance, it's just to show you the syntax, i guess. – terence hill Feb 10 '17 at 17:25
  • That's the example, sure, but that doesn't mean the example actually benefits from Numba. Heck, I doubt the example even benefits from NumPy; it probably loses more time to importing NumPy than it could save with NumPy's features. – user2357112 Feb 10 '17 at 17:26
  • @terencehill, yup – user357269 Feb 10 '17 at 17:29

1 Answers1

5

needs to compile your function based on the types of the arguments, you can either do that when defining the function by providing a signature (eager compilation) or you can let numba infer the types for you when you call the function for the first time (it's called just-in-time [JIT] compilation after all :-)).

You haven't specified any signature so it will infer and compile the function when you first call it. They even state that in the example you used:

# jit decorator tells Numba to compile this function.
# The argument types will be inferred by Numba when function is called.

However subsequent runs (with the same types and dtypes) will be fast:

t = time()
print(sum2d(a))    # 0.035051584243774414
print(time() - t)

%timeit sum2d(a)   # 1000000 loops, best of 3: 1.57 µs per loop

The last command used IPythons %timeit command.

MSeifert
  • 145,886
  • 38
  • 333
  • 352
  • TLDR; the caveat is to use the magic cell `%%timeit` that will run the cell again and make numba infer the type at every single call. Using the row magic cell `%timeit` with a pre-call to the function is better – MCMZL Feb 26 '18 at 12:42