IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

temps d'execution : Python vs Fortran


Sujet :

Python

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut temps d'execution : Python vs Fortran
    Bonjour,

    Comme j'en ai déjà parlé, j'ai un code qui s'exécute pratiquement 100 fois plus vite en Fortran qu'en Python ...

    Cet écart important me surprend car j'utilise numpy qui, je crois, accélère les calculs ...

    J'ai fait un essai sur un bout de code très simple que j'exécute un million de fois et dont je mesure le temps d'exécution ...

    verdict : 0,48 secondes en Fortran pour 9,23 secondes en Python/Numpy; soit pratiquement un facteur 40

    Et sans Numpy, le code Python met 325 secondes soit un facteur 700 !!!

    voici le bout de code en Python :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    # -*- coding: cp1252 -*-
    import numpy as np
    from time import *
    
    # creation de 5 arrays Numpy 
    dimension = 40
    f = np.ndarray(shape =(dimension),dtype=np.float)
    h = np.ndarray(shape =(dimension),dtype=np.float)
    w = np.ndarray(shape =(dimension),dtype=np.float)
    e = np.ndarray(shape =(dimension),dtype=np.float)
    t = np.ndarray(shape =(dimension),dtype=np.float)
    # remplissage des arrays Numpy
    h.fill (10.)
    w.fill (1000.)
    e.fill (290.)
    t.fill (300.)
    
    t1 = time()  # recuperation du temps système
    i = 0
    while (i < 1000000):  # execution de un million de calcul
        f = h * w * ( e - t ) # calcul
        i = i +1
    
    print 'temps pour un million de passages:', (time() - t1)
    Et pour ceux qui lisent le Fortran, le même en Fortran, les opérations Numpy sont remplacées par des boucles :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    USE DFPORT
    	implicit none
    	real t1, t2
    	real temps(2)
    	integer n, i, j
    	
    	! déclaration de 5 tableaux
    	parameter (n=40)
    	real f(n),h(n), w(n), e(n), t(n)
    	
    	! remplissage des tableaux
    	do i = 1,n
    		h(i) = 10.
    		w (i) = 1000.
    		e (i) = 290.
    		t (i) = 300.
    	enddo 
    
    	t1= dtime(temps) ! récupération du temps système avant calcul
    	do i = 1, 1000000  ! boucle pour un million de calcul
    		do j = 1, n  ! boucle remplaçant les opérations Numpy
    			f(j) = h(j) * w(j) * ( e(j) - t(j) )
    		enddo
    	enddo	
    	t2 = dtime(temps) ! récupération du temps système après calcul
    	write (6,*) 'temps pour un million de passages:',temps(1) + temps(2)
    	
    	end
    N'y a t-il pas moyen de faire plus rapide avec Python?

    En utilisant Numpy, je m'attendais à avoir quelque chose 2 à 3 fois plus lent que Fortran mais j'étais loin de penser à un facteur 40 à 100

    Est ce normal?
    Est ce que je fais quelque chose de mal?



    Bon dimanche

  2. #2
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    <Cote avis perso Cote>
    Dans un premier temps je pense qu'il serait bon de remettre les choses en place pour ce qui est de la vitesse des codes.
    Pour moi (j'espère qu'eyquem est en congé...) tu dois déjà faire la différence entre les langages interprétés, semi-compilés (donc python) et compilés. Les derniers étant dans l'absolu plus rapides que les précédents car le code est plus proche de ce qui est attendu.
    Maintenant il y à aussi la qualité du langage. Les premiers d'une classes étant meilleurs que les plus mauvais d'une autre
    Les autres facteurs étant l'optimisation du code (donc toi) et dans le cas des semi-compilés la présence de bytecode optimisé pour ce que tu cherche à faire.
    Petit aveu : Python n'est pas le plus rapide.
    <Cote avis perso Cote>

    Je ne connais pas Fortran ni numpy pour te dire si le code est optimisé.

    @+

    Ps : Je trouve que tu utilise pas mal de while dans tes codes.
    Merci d'utiliser le forum pour les questions techniques.

  3. #3
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Re,

    J'avais oublié la qualité du compilateur, cela y fais sur la rapidité du code.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  4. #4
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Merci d'utiliser le forum pour les questions techniques.

  5. #5
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Re,

    Citation Envoyé par PauseKawa Voir le message
    Les autres facteurs étant l'optimisation du code (donc toi)
    Citation Envoyé par PauseKawa Voir le message
    et dans le cas des semi-compilés la présence de bytecode optimisé pour ce que tu cherche à faire.
    Un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    t1 = time()  # recuperation du temps système
    i = 0
    while(i<1000000):  # execution de un million de calcul
        f = h * w * ( e - t ) # calcul
        i+=1
     
    print 'temps pour un million de passages:', (time() - t1)
    print f
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    patrice@Zeus:~/Bureau$ python calcultime1.py 
    temps pour un million de passages: 20.4945468903
    [-100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.
     -100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.
     -100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.
     -100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.
     -100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    t1 = time()  # recuperation du temps système
    for i in range(1000000):  # execution de un million de calcul
        f = h * w * ( e - t ) # calcul
     
    print 'temps pour un million de passages:', (time() - t1)
    print f
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    patrice@Zeus:~/Bureau$ python calcultime1.py 
    temps pour un million de passages: 18.2382779121
    [-100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.
     -100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.
     -100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.
     -100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.
     -100000. -100000. -100000. -100000. -100000. -100000. -100000. -100000.]
    Et il y a sans doute mieux.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Re bonjour PauseKawa,

    Je suis d'accord avec toi.
    Je sais qu'a priori Python n'étant pas un langage compilé, le code s'exécute plus lentement qu'un code en C ou en Fortran ...

    De là à avoir un facteur 700 sur un simple calcul avec des multiplications et des soustractions !!

    Numpy arrive à faire descendre le facteur de 700 à un peu moins de 40 ce qui reste encore énorme ...
    Un code qui s'exécute en 90 secondes en Fortran met environ une heure en utilisant Numpy et 1 jour et demi en Python pur

    Quant aux boucles while, en Python, il n'y en a qu'une: celle qui sert à faire exécuter le code plusieurs fois ....

    Dans mon cas, chaque passage dans mon jeu d'équations fait avancer mon processus de 100 microsecondes ... un peu comme si je calculais l'évolution d'un nuage en déterminant ses paramètres 10000 fois par seconde.

    J'ai choisi Python en voyant ce qui est dit ici et en estimant que cela me conviendrait ...

    Jusqu'à maintenant le temps d'exécution de mon code Python est acceptable, mais si j'augmente la taille des tableaux Numpy, ce qui revient à faire un découpage spatial plus fin de mon processus (ce que je souhaite faire) ... je pars vers des temps d'exécution prohibitifs

    Je m'oriente donc vers une mixture Fortran/Python ou C/Python qui risque de me créer beaucoup de soucis ...

    D'où mon interrogation?

    Bon dimanche

  7. #7
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Citation Envoyé par jlg_47 Voir le message
    Je m'oriente donc vers une mixture Fortran/Python ou C/Python qui risque de me créer beaucoup de soucis ...
    Pourquoi ? De toute manière le tableau final de ton lien montre que tu n'as pas le choix.

    @+

    Edit : Pour le while mon exemple avec range te montre que l'utilisation d'un build in est plus rapide.
    Merci d'utiliser le forum pour les questions techniques.

  8. #8
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    bonjour,

    à algorithme identique (ce qui est ton cas ici), un code python sera plus lent qu'un code fortran.

    là où tu peux gagner, c'est que python via ses librairies peut te permettre d'utiliser un algorithme différent, plus rapide, et qui va permettre de gagner du temps par rapport à fortran.

    dans ton cas ici, le coeur de ton problème c'est le calcul matriciel, domaine où fortran excelle donc ça ne va pas être simple et peut être même impossible.

    après tout dépend de la représentativité de ton test par rapport à ton besoin réel. ensuite, n'oublie pas de vectoriser (quand c'est possible) les calculs numpy: ils seront beaucoup plus rapides.

    mais python n'a pas besoin d'être plus rapide que le fortran, il n'en a pas besoin parce qu'un code python peut facilement communiquer avec une librairie fortran avec f2py. PauseKawa t'a donné le lien plus haut

    il n'existe pas de langage parfait, c'est à dire disposant d'une quantité presque illimitée de fonctionnalités, portable, sobre en cpu et en ram et peu couteux en terme de développement. mais il existe tellement de passerelles possibles entre le python, le c, le c++ et le fortran qu'un programme basé astucieusement sur ces langages sera franchement efficace

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Merci à tous,

    Effectivement "for" semble plus rapide que "while" ...

    Mais l'exemple que j'ai donné ne contient qu'une ligne de calcul, en réalité il y en a une vingtaine du même genre ... Donc ...

    De même, ici j'ai rempli les tableaux avec des valeurs identiques et le calcul est le même à chaque passage, mais il est bien évident que dans la réalité chaque valeur de chaque tableau est différente et évolue d'une boucle à la suivante

    Le but ici était de tester le temps de calcul, je ne pense pas que le compilo Fortran soit suffisamment intelligent pour voir que je lui demande de faire 40000000 fois le même calcul

    Je vais regarder ça
    http://cens.ioc.ee/projects/f2py2e/
    http://sourceforge.net/projects/pyfortran/
    http://fortrancython.wordpress.com/


    de très près.

    A+

  10. #10
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Bonjour,

    Sur de plus grands tableaux, numpy va se révéler plus efficace. Dans l'exemple il s'agit de petit tableaux, avec beaucoup d'aller/retour entre le Python et les fonctions de numpy.

    Comme le dit kango, il faut vectoriser quand c'est possible. Maintenant, dans ton cas, vu que tu calcules une évolution d'un processus dans le temps, cela risque d'être difficile. Mais si tu as la possibilité de caser un maximum de valeurs dans des matrices et d'appeler numpy sur celles-ci, tu devrais voir une nette amélioration.

    Si tu augmentes la taille des tableaux, ce dont tu parles, tu devrais constater que le temps d'exécution augmente proportionnellement moins vite que celui de ton code fortran.

    En modifiant ton propre exemple c'est éloquent:

    Ton code s'exécute chez moi en 8,3 secondes (dimension=40)
    Si je change dimension=400, je suis à 10,7 secondes.
    Avec dimension = 4000, je suis à 30,6 secondes.

    Je n'ai pas de compilateur Fortran sous la main, mais je suppose qu'en Fortran le temps d'exécution sera à peu de choses près proportionnel à la taille du problème. Donc si numpy était 40 fois plus lent avec dimension=40, il ne devrait être que 5 ou 6 fois plus lent avec dimension=400 et de l'ordre de 1,5 fois plus lent avec dimension=4000.

    Les fonctions de numpy sont probablement aussi rapides que ton code Fortran. En changeant la taille du problème, le temps passé hors de celles-ci (dans Python) reste plus ou moins le même (de l'ordre de 8 secondes dans l'exemple pour n=40, ça monte peut-être à 10 secondes pour n = 4000).

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 243
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par dividee Voir le message
    Si tu augmentes la taille des tableaux, ce dont tu parles, tu devrais constater que le temps d'exécution augmente proportionnellement moins vite que celui de ton code fortran.
    Merci Dividee,

    Je comprends très bien ...

    Malheureusement la vie est quelquefois difficile, si je découpe mon processus en plus petits morceaux, donc des tableaux plus grands, je dois aussi réduire le pas en temps pour que le calcul ne diverge pas

    Donc le nombre de calcul grossit de façon exponentiel ...

    dimension = 5 --> 100 calculs pour représenter une seconde suffisent
    dimension = 10 --> il en faut 1000
    dimension = 20 --> il en faut 10000

    Enfin, merci à tous, je vois mieux vers où aller maintenant ...

    De façon évidente, Python et surtout Numpy est génial pour écrire un code compact, lisible, très proche des équations mathématiques ...

    Donc Python et Numpy permettent de prototyper rapidement et vérifier que les hypothèses mathématiques tiennent la route ...

    Ensuite s'il me faut repasser à Fortran ou C, je n'en ferai pas une maladie.

    Bonne soirée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Mésurer le temps d'execution d'un programme en python
    Par mamicha dans le forum Général Python
    Réponses: 12
    Dernier message: 27/02/2015, 17h16
  2. limit et temps d'execution avec oracle et PHP
    Par dor_boucle dans le forum Oracle
    Réponses: 20
    Dernier message: 10/12/2005, 14h31
  3. Temps d'execution d'une requête
    Par Maglight dans le forum Bases de données
    Réponses: 3
    Dernier message: 27/01/2005, 08h38
  4. [VB.NET] Temps d'éxécution d'une page...
    Par Webman dans le forum ASP.NET
    Réponses: 3
    Dernier message: 04/06/2004, 12h20
  5. Connaitre le temps d'execution d'un pgm ?
    Par yacinechaouche dans le forum C
    Réponses: 7
    Dernier message: 27/01/2003, 20h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo