Quelqu'un utilise t il Nuitka ?

a marqué ce sujet comme résolu.

@buffalo974: Quel type d’application fais-tu pour nécessiter ce genre de techno ? As-tu bien identifier ton goulot d'étranglement avant de vouloir utiliser Cython ou Nuitka ? Car ce ne seront jamais des solutions magiques.

Et c'est précisément le point clé de mon post, d'ailleurs (mais c'est gentil de le trouver pertinent :)).

Oui et d'ailleurs j'avais déjà essayé de développer ce point dans mes premiers postes mais le PO semble ignorer ce point qui est le plus important.

Je ne suis pas dans la tête du PO, mais je pense qu'il cherche surtout des exemples afin de pouvoir l'appliquer par la pratique… Perso, je prépare mon nouveau PC et le temps de tout installer, je lui placerai quelques exemples. Toute façon ce genre de travail est réservé à des connaisseurs python/C et python/C++, l'un va pas sans l'autre, donc si buffalo974 ne connaît pas le C ou le C++ il peut oublier à moins de vouloir faire un programme exécutable à partir de son fichier python.

ben je pense débuter le c++ depuis 6 mois déjà mais je trouve toujours des trucs cool en python à creuser, alors ça finira par venir… disons que le c++ m' apportera des connaissances complémentaires au python. Connaître les deux c'est super je pense.

Plus que des connaissances complémentaires, il consolidera ta boîte à outils en te donnant les moyens d'aller titiller le sillicium dans les moments où Python s'essouflera en termes de calcul pur. Je ne peux que t'encourager sur cette voie. :)

+0 -0

Bon chose promise, …

On va prendre un cas simple pour voir facilement les différences avec une problématique bien connue qui est fibonacci. On peut le retrouver facilement sur la toile à toutes les sauces.

On va prendre un cas très défavorable pour python, la fonction récursive, testée avec python 3.5

Avant on vérifiera que cython est bien installé, et que les dépendances le sont elles aussi.

fib.py

1
2
3
4
def fib_py(n):
    if n < 2:
        return n
    return fib_py(n-2) + fib_py(n-1)

En cython, fib_cython.pyx

1
2
3
4
5
6
7
def fibb(int n):
    return fib_in_c(n)

cdef int fib_in_c(int n):
    if n < 2:
        return n
    return fib_in_c(n-2) + fib_in_c(n-1)

fibb est la fonction qui sera utilisé pour son retour et qui sera un objet python, très important !

setup.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [
    Extension('fib_cython',
              ['fib_cython.pyx'])]
setup(
  name = 'my cython fibonacci',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)

Souvent plus simple que de se taper les longues lignes de compilation,

Un petit

1
python3 setup.py build_ext --inplace

On nous ramène un fichier avec l'extension so (nommé fib_cython.so dans l'exemple), c'est la libC qu'on utilisera pour importer dans le fichier principal python

so pour Unix, dll ou pyd pour Windows concernant les extensions créées par le setup.

test.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from fib import fib_py
from fib_cython import fibb
from time import clock

times = [0, 0]

for ind, f in enumerate((fib_py, fibb)):
    start = clock()
    res = f(38)
    times[ind] = clock()-start
    print("temps pour la fonction {}: {}".format(f.__name__, times[ind]))

print("cython est {} fois plus rapide".format(times[0]/times[1]))

Nos tests, enfin…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
fred1599@Fred:~/Bureau$ python3 test.py
temps pour la fonction fib_py: 21.966182
temps pour la fonction fibb: 0.25559200000000004
cython est 85.94236908823436 fois plus rapide

fred1599@Fred:~/Bureau$ python3 test.py
temps pour la fonction fib_py: 23.007478000000003
temps pour la fonction fibb: 0.24599800000000016
cython est 93.52709371620902 fois plus rapide

fred1599@Fred:~/Bureau$ python3 test.py
temps pour la fonction fib_py: 22.220582
temps pour la fonction fibb: 0.24598800000000054
cython est 90.33197554352225 fois plus rapide

On voit qu'on tourne aux alentours de 90x le temps imparti par python.

C'est le pire des cas, si on prend l'exemple d'une fonction itérative (tiens un exercice pour toi), tu te rendras compte que le ratio est moins important. En général on tourne entre 10 et 25x le temps python, mais avant cython, il faut:

  1. Vérifier que l'algorithme choisi est efficace
  2. Utiliser au maximum les modules résultant d'un binding C (split, strip, sum, …)
  3. Utiliser numpy avant cython si possible
  4. Utiliser cython en cas de détresse (temps par exemple ne respectant pas les objectifs)

Bonne continuation…

+3 -0

Et encore il faut s'assurer qu'on n'optimise pas dans le vide avant.

Parce qu'un x10, ça peut paraître dérisoire à côté d'un x100, mais ce x10 appelé sur la bonne fonction peut te faire faire littéralement des bonds dans la globalité du programme (il suffit qu'il soit appelé 100 fois dans une boucle pour devenir un x1000…), de même qu'un x100 sur une autre fonction du programme peut très bien te faire gagner à peine 3% dans le temps d'exécution du soft.

Pour moi, si on se lance dans cython, il faut également apprendre à se servir du module standard cProfile, et/ou des packages line_profiler et/ou flamegraph sur le Pypi. Sinon c'est comme apprendre à se servir d'un marteau avant même de savoir tenir un clou.

C'est d'autant plus important que la cythonisation est vraiment un dernier recours quand on a déjà optimisé tout le reste.

+4 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte