Numba makes python code run slower in a simple for-loop (Not using numpy)

Viewed 99

I'm trying to play with Numba and tried to run this code (mapping a big list):

from numba import njit, jit
from datetime import datetime


big_list = [(i, i + 10000) for i in range(1, 100000000)]

#Just a number of arithmetic operations (Using Numba).
@njit(cache=True)
def just_calc_jit(row):
    exp_1 = row[1] / row[0]
    exp_2 = (row[0] + 10000) / row[1]
    exp_3 = (exp_2 - row[0]) / exp_1
    exp_3 *= exp_3
    return exp_3

# Same function without Numba.
def just_calc(row):
    exp_1 = row[1] / row[0]
    exp_2 = (row[0] + 10000) / row[1]
    exp_3 = (exp_2 - row[0]) / exp_1
    exp_3 *= exp_3
    return exp_3

# Prints execution times (with and without Numba) 5 times for every function.
for i in range(5):
    start = datetime.now()
    result = list(map(just_calc, big_list))
    execution_time = datetime.now() - start
    print("execution time:", execution_time)

    start = datetime.now()
    result = list(map(just_calc, big_list))
    execution_time = datetime.now() - start
    print("execution time jit:", execution_time)

This is the output of the script (You can see the execution time with and without using Numba 5 times for each):

execution time: 0:00:17.643550
execution time jit: 0:00:19.780514
execution time: 0:00:19.072673
execution time jit: 0:00:18.961395
execution time: 0:00:20.567786
execution time jit: 0:00:20.119370
execution time: 0:00:21.254276
execution time jit: 0:00:20.034304
execution time: 0:00:20.219750
execution time jit: 0:00:19.237941

What am I missing/doing wrong?

1 Answers

I change two things in your code and get a better result in run-time with numba: (In the first run of the numba functions, we get a bad result.)

  1. loop over rows of big_list in the functions.
  2. Input big_list as numpy.asarray to functions.
from datetime import datetime
import numba as nb
import numpy as np


big_list = [(i, i + 10_000) for i in range(1, 100_000)]

#Just a number of arithmetic operations (Using Numba).
@nb.njit(parallel = True)
def just_calc_jit(arr):
    num_row = len(arr)
    res = np.empty((num_row))
    for i in nb.prange(num_row):
        exp_1 = arr[i][1] / arr[i][0]
        exp_2 = (arr[i][0] + 10000) / arr[i][1]
        exp_3 = (exp_2 - arr[i][0]) / exp_1
        exp_3 *= exp_3
        res[i] = exp_3
    return res

# Same function without Numba.
def just_calc(arr):
    num_row = len(arr)
    res = np.empty((num_row))
    for i in range(num_row):
        exp_1 = arr[i][1] / arr[i][0]
        exp_2 = (arr[i][0] + 10000) / arr[i][1]
        exp_3 = (exp_2 - arr[i][0]) / exp_1
        exp_3 *= exp_3
        res[i] = exp_3
    return res

# Prints execution times (with and without Numba) 5 times for every function.
for i in range(5):
    start = datetime.now()
    result = just_calc(np.asarray(big_list))
    execution_time = datetime.now() - start
    print("execution time:", execution_time)

    start = datetime.now()
    result = just_calc_jit(np.asarray(big_list))
    execution_time = datetime.now() - start
    print("execution time jit:", execution_time)

Output: (Benchmark on colab)

execution time: 0:00:00.323675
execution time jit: 0:00:00.639346
execution time: 0:00:00.237574
execution time jit: 0:00:00.046685
execution time: 0:00:00.222264
execution time jit: 0:00:00.048550
execution time: 0:00:00.223323
execution time jit: 0:00:00.049903
execution time: 0:00:00.222570
execution time jit: 0:00:00.049623
Related