Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
exemple_cython_cpp [2013/10/17 12:42] tyrtamos |
exemple_cython_cpp [2013/10/18 18:20] tyrtamos |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
====== Exemple d' | ====== Exemple d' | ||
- | |||
- | |||
- | **//En cours de construction// | ||
- | |||
===== Objectif ===== | ===== Objectif ===== | ||
Ligne 15: | Ligne 11: | ||
La fonction choisie pour l' | La fonction choisie pour l' | ||
- | Suggestion: si vous voulez construire les 3 exemples ci-dessous et en faire des comparaisons de performances, | + | Suggestion: si vous voulez construire les 3 exemples ci-dessous et en faire des comparaisons de performances, |
+ | |||
+ | < | ||
+ | essaicython (répertoire) | ||
+ | test.py (code de test des 3 exemples) | ||
+ | |||
+ | pgcd1 (répertoire) | ||
+ | __init__.py | ||
+ | ... (code de l' | ||
+ | |||
+ | pgcd2 (répertoire) | ||
+ | __init__.py | ||
+ | ... (code de l' | ||
+ | |||
+ | pgcd3 (répertoire) | ||
+ | __init__.py | ||
+ | ... (code de l' | ||
+ | </ | ||
+ | |||
+ | Cela vous permettra de tester les 3 exemples dans un programme test, dans lequel vous pourrez importer les 3 pgcd comme suit: | ||
<code python> | <code python> | ||
Ligne 22: | Ligne 37: | ||
from pgcd3.pgcd3 import pgcd3 | from pgcd3.pgcd3 import pgcd3 | ||
</ | </ | ||
+ | |||
+ | Attention sous Windows: choix du compilateur | ||
+ | |||
+ | Python prendra le compilateur par défaut. Si vous avez Visual Studio de Microsoft (comme moi), c'est lui qui sera utilisé (ça fonctionne très bien!). Mais si vous voulez MinGW au lieu de Visual Studio, il y a 2 choses à faire: | ||
+ | |||
+ | 1- créer un fichier texte “setup.cfg” placé au même niveau que setup.py, et contenant: | ||
+ | |||
+ | < | ||
+ | [build] | ||
+ | compiler = mingw32 | ||
+ | </ | ||
+ | |||
+ | 2- corriger le fichier C: | ||
+ | |||
+ | Moyennant quoi, chez moi, ça marche avec les 2 compilateurs. | ||
===== Fonction codée en Python pur ===== | ===== Fonction codée en Python pur ===== | ||
Ligne 41: | Ligne 71: | ||
Il est difficile de faire plus simple! | Il est difficile de faire plus simple! | ||
- | |||
- | L' | ||
- | |||
- | <code python> | ||
- | from pgcd1 import pgcd1 | ||
- | </ | ||
===== Fonction codée en Cython pour être compilée en C++ ===== | ===== Fonction codée en Cython pour être compilée en C++ ===== | ||
Ligne 77: | Ligne 101: | ||
A noter que j' | A noter que j' | ||
- | Pour le tratement | + | Pour le traitement |
<code python> | <code python> | ||
Ligne 99: | Ligne 123: | ||
Vous voyez que c'est dans le setup qu'on désigne le C++ comme choix du compilateur. | Vous voyez que c'est dans le setup qu'on désigne le C++ comme choix du compilateur. | ||
- | |||
- | |||
Il ne reste plus qu'à exécuter le traitement par (à exécuter dans le répertoire du setup): | Il ne reste plus qu'à exécuter le traitement par (à exécuter dans le répertoire du setup): | ||
Ligne 106: | Ligne 128: | ||
< | < | ||
python setup.py build_ext --inplace | python setup.py build_ext --inplace | ||
- | </ | ||
- | |||
- | L' | ||
- | |||
- | <code python> | ||
- | from pgcd2 import pgcd2 | ||
</ | </ | ||
Ligne 122: | Ligne 138: | ||
**bib.cpp**: | **bib.cpp**: | ||
- | < | + | < |
#include " | #include " | ||
Ligne 138: | Ligne 154: | ||
Et l' | Et l' | ||
- | < | + | < |
int pgcd_(int a, int b); | int pgcd_(int a, int b); | ||
</ | </ | ||
Ligne 198: | Ligne 214: | ||
</ | </ | ||
- | Et le module final pgcd3.pyd pourra être importé avec: | + | ===== Utilisation et test de performance ===== |
+ | |||
+ | Voilà | ||
<code python> | <code python> | ||
- | from pgcd3 import pgcd3 | + | # |
+ | # -*- coding: utf-8 -*- | ||
+ | from __future__ import division | ||
+ | # Python 2.7 | ||
+ | |||
+ | from pgcd1.pgcd1 import pgcd1 | ||
+ | from pgcd2.pgcd2 import pgcd2 | ||
+ | from pgcd3.pgcd3 import pgcd3 | ||
+ | |||
+ | from timeit import default_timer | ||
+ | from random | ||
+ | |||
+ | n = 1000000 | ||
+ | a = randint(10, | ||
+ | b = randint(10, | ||
+ | |||
+ | t1 = default_timer() | ||
+ | for c in xrange(0, n): | ||
+ | pgcd1(a, b) | ||
+ | t1 = default_timer()-t1 | ||
+ | print t1 | ||
+ | |||
+ | t2 = default_timer() | ||
+ | for c in xrange(0, n): | ||
+ | pgcd2(a, b) | ||
+ | t2 = default_timer()-t2 | ||
+ | print t2 | ||
+ | |||
+ | t3 = default_timer() | ||
+ | for c in xrange(0, n): | ||
+ | | ||
+ | t3 = default_timer()-t3 | ||
+ | print t3 | ||
+ | print t2/t1, t3/t2 | ||
</ | </ | ||
+ | Exemple d' | ||
+ | |||
+ | < | ||
+ | 1.51095759895 | ||
+ | 0.330764389199 | ||
+ | 0.295863063216 | ||
+ | 0.218910437612 0.894482818819 | ||
+ | </ | ||
+ | |||
+ | Constatations: | ||
+ | |||
+ | * le temps d' | ||
+ | |||
+ | * Lorsque Cython appelle directement du code C++, on gagne encore 10% environ. Ce qui peut être intéressant si on dispose déjà du code C++, mais pas assez s'il faut l' | ||
+ | |||
+ | Conclusion: **//la solution " | ||
+ | |||
+ | Attention cependant: lorsqu' | ||
+ | |||
+ | Amusez-vous bien! | ||