Boostez Python avec Cython et IPython

L'algorithmique est maintenant massivement enseignée mais l'algo ne fait pas tout...

Pour des élèves débutants initiés à Python mais ne connaissant pas C, il est possible, comme M. Jourdain, de faire du C sans le savoir en utilisant Cython. Dans les cas les plus simples, cela revient grosso-modo à écrire du Python mais en déclarant le type des variables.

Pour éviter les contraintes de compilation qui pourraient effrayer les non-informaticien(ne)s, on peut utiliser dans une même session IPython (ou le notebook de Sage), Python et Cython.




=> SESSION IPYTHON correspondante.



En gros on compare:

Python
In [4]: %%cython
cdef double cf(double x):    
   return x**2 - 2 * x
 
def cintegre(double a, double b, int N):
    cdef int i
    cdef double s, dx
    s  = 0
    dx = (b - a) / N
    for i from 0 <= i < N:
        s += cf(a + i*dx)
    return s*dx

qui tourne vite:

Python
In  [15]: %timeit cintegre(0,2,2**20)
Out [15]: 100 loops, best of 3: 4.76 ms per loop

et

Python
def f(x):    
   return x**2 - 2 * x
 
def integre(a, b, N):
    s  = 0    
    dx = (b - a) / N
    for i in range(N):   
       s += f(a + i*dx)
    return s*dx

qui tourne lentenment:

Python
In  [11]: %timeit integre(0.,2.,2**20)
Out [11]: 1 loops, best of 3: 417 ms per loop

Le code C similaire serait:

C
#include <stdio.h>
#include <math.h>
 
double integre(double,double,int);
double f(double);
 
void main(void)
{ double it;
  it = integre(0,2,pow(2,20));
  printf("L'intégrale cherchée est %f \n", it);
}
 
double integre(double a, double b, int N)
{ int i;
  double s, dx;
  s = 0;
  dx = (b - a) / N;
  for (i = 0; i < N; i++)
    {s = s + f(a + i*dx);
    }
  return s*dx;
}
 
 
double f(double x)
{ 
  return x*x - 2*x;
}

alors on obtient à la compilation:

Bash
$ gcc -o compareCythonC compareCythonC.c
$ time ./compareCythonC 
L'intégrale cherchée est -1.333333 
 
real    0m0.023s
user    0m0.023s
sys     0m0.000s

23 ms alors qu'avec cython, on a obtenur 4.8 ms. C'est que Cython code mieux en C que nous ;-) Le fichier C créé fait pourtant 2125 lignes....