Génération vecteur de valeurs¶

In [1]:
#Python
import sys
sys.version
Out[1]:
'3.12.7 | packaged by Anaconda, Inc. | (main, Oct  4 2024, 13:17:27) [MSC v.1929 64 bit (AMD64)]'
In [2]:
#numpy
import numpy
numpy.__version__
Out[2]:
'1.26.4'
In [3]:
#nombre de valeurs
n = 5000
In [4]:
#vecteur de valeurs
rng = numpy.random.default_rng(seed=2024)
v = rng.random(size=n)
v.shape
Out[4]:
(5000,)

Programme recherche extremum¶

In [5]:
#sans directive particulière
#side = 0 -> min ; side != 0 -> max
def extremum(x,side):
    #copie locale
    vec = numpy.copy(x)
    n = len(vec)
    #tri à bulles -- https://fr.wikipedia.org/wiki/Tri_à_bulles
    for i in range(n-1,0,-1):
        for j in range(0,i):
            if (vec[j+1] < vec[j]):
                temp = vec[j+1]
                vec[j+1] = vec[j]
                vec[j] = temp
    #déterminer l'extremum à renvoyer
    res = vec[0] if side == 0 else vec[-1]
    #renvoyer l'extremum
    return res
In [6]:
#programme pour recherche de l'étendue
def etendue(x):
    result = numpy.zeros(2)
    for i in range(2):
        result[i] = extremum(x,i)
    #etendue = max - min
    return result[1]-result[0]
In [7]:
#exécution sur notre vecteur
print(etendue(v))
0.9994010899616623
In [8]:
#temps de calcul
%timeit etendue(v)
9.18 s ± 179 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Compilation avec Numba¶

In [9]:
#version de numba
import numba
numba.__version__
Out[9]:
'0.60.0'
In [10]:
#pour compilation
from numba import njit

#extremum avec Numba
@njit
def extremum_numba(x,side):
    #copie locale
    vec = numpy.copy(x)
    n = len(vec)
    #tri à bulles -- https://fr.wikipedia.org/wiki/Tri_à_bulles
    for i in range(n-1,0,-1):
        for j in range(0,i):
            if (vec[j+1] < vec[j]):
                temp = vec[j+1]
                vec[j+1] = vec[j]
                vec[j] = temp
    #déterminer l'extremum à renvoyer
    res = vec[0] if side == 0 else vec[-1]
    #renvoyer l'extremum
    return res
In [11]:
#et l'étendue
@njit
def etendue_numba(x):
    result = numpy.zeros(2)
    for i in range(2):
        result[i] = extremum_numba(x,i)
    #etendue = max - min
    return result[1]-result[0]
In [12]:
#relancer
print(etendue_numba(v))
0.9994010899616623
In [13]:
#temps de calcul
%timeit etendue_numba(v)
37.2 ms ± 794 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Parallélisation¶

In [14]:
#itération parallèle
from numba import prange

#etendue avec parallélisation
@njit(parallel=True)
def etendue_numba_parallele(x):
    result = numpy.zeros(2)
    #les deux itérations sont lancées en parallèle
    for i in prange(2):
        result[i] = extremum_numba(x,i)
    #etendue = max - min
    return result[1]-result[0]
In [15]:
#vérification
print(etendue_numba_parallele(v))
0.9994010899616623
In [16]:
#temps de calcul
%timeit etendue_numba_parallele(v)
18 ms ± 153 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)