Python, Ruby et PHP sont lents


Ce matin je lançais ma petit recherche Python/Django/Git habituelle sur Twitter pour voir ce qui s’y tramait, quand je suis tombé sur plusieurs tweets qui m’ont fait tiquer.

Il y en a un qui résume très bien l’idée:

Cay de la merde je préfère les langages plus bas niveau, Python c’est lent.

C’est un argument que je lis souvent, et qui est aussi utilisé contre Ruby ou PHP.

Si j’ai la personne en face de moi, généralement la question qui suit est:

Ouai je comprends. C’est quoi ta contrainte ? Tu dois exécuter quel calcul sous quelle limite de temps ?

Il n’y a jamais aucune réponse autre qu’un bafouillement, car une personne qui a une réelle contrainte de temps d’exécution ne sort pas ce genre d’ânerie: il utilise le bon outil pour le bon travail selon des metrics précises, pas selon le nom du langage.

Ceux qui trollent, généralement des étudiants en informatique qui n’ont encore jamais codé d’utile de leur vie (je l’ai fait, donc je +1, d’ailleurs parfois je le fais toujours :-p), ont entendu / lu que Python, Ruby et PHP étaient lents, et donc les rejette car ils ne correspondent pas à l’idée qu’il se fait de la programmation, encore naissante dans sa tête.

La vérité est que les personnes qui ont des contraintes de temps d’éxécution auquel langage X, n’importe quel langage, ne peut pas répondre, font partie des 0.00000001 de la population des programmeurs: le plus souvent dans l’embarqué (voiture, satellite, microchips, etc) et les systèmes temps réels (navigation, chaîne de productions, bourse d’échange…). Pour les autres, nous, quasiment tous, les problèmes de performances se joueront sur l’algo, les libs, les serveurs Web et BDD, le caching, etc. On peut programmer en Basic ou en GOTO++, ça ne change rien.

Languages, libraries and frameworks don’t scale. Architectures do.

Cal Henderson

Dans certains cas, par exemple le calcul scientifique, les interfaces graphiques ou les jeux videos, la rapidité est importante, et on le sait sans même mesurer. Mais ces problèmes-là sont résolus depuis longtemps: il existe des bindings en C extrêmement rapides qui permettent de coder dans son langage interprété favori tout en bénéficiant d’algos Speedy Gonzalez sous le capot.

Par ailleurs, ça a déjà été dit 1000 fois, mais ça ne fait pas de mal de le répéter:

Le salaire du développeur et l’impact commercial de la lenteur d’un développement coûtent immensément plus cher qu’un ordinateur plus puissant. Qui d’ailleurs ne coûtera plus rien dans 6 mois.

Alors OK, ce n’est pas une invitation à coder avec ses pieds sous prétexte qu’on la puissance à disposition (ce qui se fait malheureusement de plus en plus).

Mais choisissez une techno parce que vous êtes productif avec, pas pour ses performances. Sauf si vous avez des mesures chiffrées qui s’imposent à vous. Auquel cas vous n’avez de toute façon pas besoin de lire cet article, vous êtes plus compétent que moi.

30 thoughts on “Python, Ruby et PHP sont lents

  • Freak0

    Dans une boite précédente, l’ingé qui gérait le système de facturation de SMS surtaxés, a réussis à diviser par 800 le temps de traversée (traitement de bout en bout) des d’un SMS.

    Pas en changeant de langage (java), en changeant de méthodes de conception, en évitant les goulets d’étranglements BDD entre autre, et en partant du principe qu’il pourra toujours rajouter de la mémoire son application mettait 30 minutes à charger, la base de 12GO mais après il n’y a faisait que des accès bulk de Maj/Lecture, plutot que pleins de petits accès, il utilisait des concepts récents genre in-memory, …

    Bien souvent il suffit de coder et de penser l’application différemment pour améliorer ses traitements et les adapter à son environnement. Après les gens qui ont besoin d’une puissance brute, comme dit plus haut, ils en savent plus que nous.

  • Fab

    +1 : dans ma boîte où nous développons des modules pour un ERP (en python :)), on a été capable de faire passer la génération d’un rapport de 45minutes à 2 minutes 30.
    Le système faisait initialement plusieurs centaine de milliers de petites requêtes SQL pour récupérer l’info… Nous avons préféré tout récupérer d’un coup, stocker le tout en mémoire (quelques dizaine de méga octets au final, rien de bien méchant) et piocher dans cette structure de dicos imbriqués pour accéder à nos données. Et 2 minutes 30 pour générer un fichier xls 30*30000, c’est acceptable.

  • Kontre

    Je suis d’accord avec vous sur le plan général, mais je développe des algos scientifiques moi-même, et malheureusement on perd beaucoup de performance en python. Du coup Speedy Gonzalez ne m’avance pas à grand chose puisqu’il court dans la mauvaise direction…

    De plus, c’est un brin naïf (pas trouvé de meilleur mot) de croire que si on a des contraintes (de temps ou de volume de calcul) alors on sait forcément comment faire. Je n’ai toujours pas trouvé de langage “haut niveau” qui me donne des performances similaires au C (pour le même algo of course).

    J’adore python, je fais le maximum de choses avec, mais j’ai toujours des cas où ça coince, et je ne suis malheureusement pas plus compétent que vous ! ;)

    Par contre, en quoi les interfaces graphiques nécessitent tant de rapidité que ça ? (je ne parle pas du framework lui-même, mais de son utilisation)

    • Max

      rien à voir avec la choucroute mais @kontre si je te file une formule scientifique tu saurais me la retranscrire en python ?

    • Max

      doit pas être dur pour qui s’y connait, c’est du traitement d’image, detection des blocks dû à forte compression du format JPEG

  • LB

    @kontre : pour le calcul scientifique : cython + numpy est très très rapide, avec du même mpi sous le capot dans les dernières version.

  • Sam Post author

    @Kontre: +1 avec LB. Numpy et Scipy rendent Python suffisament rapide pour 90% des calculs scientifiques.

  • Kontre

    @LB Ouaip, je fouille là-dedans, ça a l’air bien mais il ma manque encore le déclic qui me fera “ah mais c’est comme ça que ça marche, c’est tout con !”.

    @Max: Je confirme ce que dit Fab, ça dépend de la formule, et tu as plutôt l’air de parler d’un algo complet que d’une bête équation. Je m’y connais pas plus que ça en traitement d’image, mais si tu as déjà le principe ça peut se faire. Envoie, on sait jamais (ou fait un “concours” ici, je dois pas être le seul scientifique à traîner dans le coin).

  • VonTenia

    Premature optimization is the root of all evil…
    http://c2.com/cgi/wiki?PrematureOptimization

    Après comme vous dites, c’est pas une raison pour ne pas optimiser quand on le peut (et qu’on sait le faire). Je pense que ça vient aussi avec l’expérience (choisir un SMALLINT unsigned au lieu d’un INT pour une colonne indexée sur une table avec un milliard d’enregistrements, ça fait la différence parfois).

  • Max

    @kontre, aller chiche on en fait un…(Lagaf, bo le lavabo)

    Explicatios, le principe est pas compliqué mais faut être matheux et savoir se servir de MAtlab. En gros le concept est de détecter les blocks(artifacts) générés par une trop grosse compression JPEG.
    https://ece.uwaterloo.ca/~z70wang/publications/icip02.pdf

    Il a transcrit sa formule en matlab dispo ici:
    http://signal.ece.utexas.edu/~zwang/research/nr_jpeg_quality/jpeg_quality_score.m

    Je suis en train d’essayer de la retranscrire en python avec Numpy et PIL à l’aide de ce tableau d’équivalence:
    http://mathesaurus.sourceforge.net/matlab-python-xref.pdf

    Je suis pas bon au point de comprendre la formule mais je comprends le principe car le mec l’a bien expliqué donc je vais persévérer j’usqu’à ce que j’y arrive :)

    Ceux que ça tente de retranscrire son script matlab en Python je vous mettrai un tampon :)

    PS: Bordel c’est quand qu’on le sort ce StackOverflow Français ?!

  • Sam Post author

    Max: mieux. On fait un tampon spécial juste pour le mec qui donne la soluce ?

  • Kontre

    Voilà ! http://pastebin.com/pDdw3eXX

    A partir de code Matlab c’est super facile ! J’ai vérifié avec Octave, ça renvoie bien les mêmes valeurs. Pour tester j’ai pris les images en exemple sur la page wikipedia que tu as linkée, mises en noir et blanc.

    À moi le tampon ! ;)

  • Sam Post author

    Si ça marche, tu veux quoi comme tampon ?

    Moi je pensais à un truc du genre “Y a du pour et du Kontre”. Mais tu peux choisir :-)

  • Max

    meeeeeerde va falloir lui faire un tampon, bon moi ça me sort de la merde car j’avais testé de mon côté pdt ce temps genre :

    octave:52> jpeg_quality_score(image)
    ans = 7.4360
    octave:53> jpeg_quality_score(imread(‘/tmp/good1.jpeg’))
    ans = 8.1997
    octave:54> jpeg_quality_score(imread(‘/tmp/good2.jpeg’))
    ans = 8.1871
    octave:55> jpeg_quality_score(imread(‘/tmp/good3.jpeg’))
    ans = 7.5534
    octave:56> jpeg_quality_score(imread(‘/tmp/bad.jpeg’))
    ans = 7.4438
    octave:57> jpeg_quality_score(imread(‘/tmp/bad2.jpeg’))
    ans = 8.2158

    valeurs batardes…

    Je teste le tiens, j’ai ptet merdé kekke part…

  • Max

    question: imread() d’Octave les fout pas en N&B directos ? y a une manip à faire entre les deux ?

  • Max

    pour que le script marche j’ai du convertir l’image en gris:

    img = np.array(Image.open(filename).convert(L))

    au lieu de

    img = np.array(Image.open(filename))

  • Sam Post author

    Hey, sale lapin psychopathe, tu lui a même pas laissé le temps de répondre !

  • Kontre

    Nickel le tampon ! Je l’encadrerai sur un mur dans ma chambre !

    Les versions noir et blanc je les ai fait à la main (mais ça se fait aussi facile en python ou Matlab, j’ai juste eu la flemme de réflméchir)

    Pour info, voilà mes scores :
    http://imageshack.us/photo/my-images/203/segolilycmnb.jpg/ => 10.377
    http://imageshack.us/photo/my-images/832/segolilycm150nb.jpg/ => 0.79191

    D’après l’aide, imread() sort un tableau de MxN pour du noir et blanc et MxNx3 pour de la couleur (RGB), comme python. Pour passer en noir et blanc, le plus simple est de faire la moyenne des 3 canaux, pour cette fonction ça doit suffire. Il suffit de rajouter ce code après la lecture de l’image :
    if img.ndim == 3:
    . . img = np.mean(img, 2)

  • Kontre

    Max, non seulement tu spammes, mais en plus c’est hors sujet ;) Au passage, on voit bien sur ce genre de fonctions qu’un langage interprété va aussi bien qu’autre chose…

    J’aurai appris la conction convert, c’est plus élégant que ma somme (même si je suppose que le résultat est identique, “There should be one– and preferably only one –obvious way to do it.”)

    • Max

      héhé, en tous cas merci mec ;).
      C’est cool qu’on puisse l’adapter aussi “facilement” sous Python quand même. la classe à Dallas

    • Max

      @claus

      ouais mais ça me fait chier de dépendre d’eux. c’est plus le côté aventure qui me botte. je t’expliquerai…(Popeye dans les bronzés font du ski)

  • Sam Post author

    Perso j’ai une réputation de plus de 50000 sur SO. Je me sens pas motivé de faire la même chose sur la version française si c’est pas la mienne. C’est un boulot de fou en plus du blog. Sans compter les forums où j’officie. C’est un coup à finir schyzo.

  • tshirtman

    C’est clair, 99% des programmes sont bien plus io-bound, que cpu-bound, et c’est donc bien plus important de penser sa conception que de choisir le langage le plus rapide, par ce que si tu code mal, il fera pas de miracle… mais va expliquer ça au petit nouveau… après oui, y’a cython et compagnie pour quand y’a besoin, mais j’ai toujours du mal avec, c’est quand même un peu batard comme truc ^^.

  • Victor STINNER

    Je bosse dans la télévision numérique, dans l’embarqué. Bah Python convient très bien. Maitenant les telephones ont 1 Go de ram, un gpu et un cpu avrc deux coeurs.

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.