Forum Programmation.c Je veux bien que JavaScript soit optimisé, mais quand même !...

8
26
juin
2024

Bonjour à tou(te)s,

je veux bien que JavaScript soit optimisé, mais quand même, de là à être du même ordre de grandeur que C en calcul simple je ne comprends pas ! En effet C étant un langage compilé et typé, je pensais que sur les calculs il serait au moins un ou deux ordres de grandeur plus rapide, mais pas du tout !

J'avoue : je n'avais pas retouché à C depuis au moins 10 ans, je suis donc bluffé par les progrès de vitesse d'exécution des langages type JavaScript.

Les Détails

Une amie a son fils qui passe le grand oral du bac en maths sur "Approximation de PI par l'intégrale de Wallis".
Python sur son ordinateur étant un peu lent, je me suis dit tiens je vais le refaire en JavaScript et c'était effectivement plus rapide.
Puis je me suis dit tiens le programme est tellement simple et court que je vais ressortir le C du placard ! Surtout que ce qui est rigolo est que vu de loin la syntaxe du JavaScript est proche de celle du C.

Et là incroyable !!! Le C est plus lent, jusqu'à ce que je compile avec l'option -O3 ! Et même avec ça la différence est minime (quelques % d'écart) !!!

S'il y a des spécialistes dans le coin (et il y en a j'en suis sûr), je veux bien des explications. La seule qui me vient est que le calcul avec des double est tellement lent que le reste est négligeable, mais ça me convient moyen comme explication…

Le code Javascript et ses résultats

    function wallis(n){
        let a=1.0;
        let b=1;
        t = performance.now();
        for(let i=1; i<=n ; i++){
            a=a*((4.0*i**2)/(4.0*i**2-1));
            if(i==10*b){
                console.log(a*2, ", time=", (performance.now()-t)/1000.);
                t = performance.now();
                b=i;
            }
        }
        return a*2;
    }

    wallis(10**9);


3.0677038066434985 ', time=' 0
3.133787490628162 ', time=' 0
3.140807746030402 ', time=' 0.000
3.1415141186819566 ', time=' 0.001
3.141584799657247 ', time=' 0.001
3.141591868192149 ', time=' 0.003
3.1415925750808533 ', time=' 0.011
3.141592643066262 ', time=' 0.097
3.141592643066262 ', time=' 0.972
3.141592643066262

Le code C et ses résultats

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h>

    double now(){
        struct timespec t;
        clock_gettime(CLOCK_MONOTONIC, &t);
        return t.tv_sec + t.tv_nsec /1000000000.;
    }


    double wallis(unsigned long n){
        double a = 1.;
        unsigned long b = 10;

        double t = now();
        for(unsigned long i = 1; i<=n ; i++){
            a *= (4.*i*i)/(4*i*i-1);
            if(i==b){
                double t2 = now();
                printf("%.16f, time=%.3fs\n", a*2, (t2-t));
                t = t2;
                b *= 10;
            }
        }
        return a*2;
    }

    int main(){
        unsigned long n = pow(10,9);
        printf("%.16f\n",wallis(n));
        return 0;
    }

3.0677038066434985, time=0.000s
3.1337874906281620, time=0.000s
3.1408077460304020, time=0.000s
3.1415141186819566, time=0.000s
3.1415847996572470, time=0.000s
3.1415918681921489, time=0.001s
3.1415925750808533, time=0.013s
3.1415926430662622, time=0.092s
3.1415926430662622, time=0.916s
3.1415926430662622

  • # l'appel à clock_gettime / now ?

    Posté par  . Évalué à 5.

    essaye de supprimer l'appel pour avoir la temps. j'ai pas testé en c, mais en js je passe de 2sec à 1.5sec.
    peut-etre que js a une astuce pour avoir un timestamp plus efficace qu'un appel système.

    • [^] # Re: l'appel à clock_gettime / now ?

      Posté par  (site web personnel) . Évalué à 3. Dernière modification le 26 juin 2024 à 18:10.

      Ces appels n'ont lieu que 9 fois sur un milliard, ça ne change pas le fait qu'on reste dans le même ordre de grandeur entre C et JS.

      • [^] # Re: l'appel à clock_gettime / now ?

        Posté par  . Évalué à 8.

        9 appels systems, sur des calculs qui peuvent se faire sans cache miss, vu la vitesse des procs actuels, ça peut jouer (ça représente quand même 25% du temps total sur mon test).

  • # Optimisation spécifique?

    Posté par  . Évalué à 6. Dernière modification le 26 juin 2024 à 17:44.

    En fait, l'algo est tellement simple qu'il doit passer une grosse partie du temps sur i**2. Si le compilo C ne voit pas qu'il peut calculer 4*i*i une seule fois avant -O3, il part avec un désavantage. À moins que ça soit une typo, le code C est 4.*i*i/(4*i*i-1), si ça se trouve le compilo calcule 4.*i*i en double, et 4*i*i en long int, il fait donc deux fois le calcul.

    Si ça n'est pas ça, est-ce qu'il n'y aurait pas des implémentations spécifiques de i**2 qui sont plus rapides que i*i? C'est certain que pour i**10, il ne fait pas i*i*i*i*i*i*i*i*i*i, donc il doit y avoir un compromis sur la rapidité entre appeler la fonction puissance et faire la multiplication.

    • [^] # Re: Optimisation spécifique?

      Posté par  (site web personnel) . Évalué à 2.

      Ce n'est une typo, 4.*i*i/(4.*i*i-1) est identique ou un poil plus lent que 4.*i*i/(4*i*i-1). Je suis obligé de garder le 1er 4 en virgule flottante sinon les résultats sont faux ou bien je suis obligé de mettre a = a * au lieu de a *= ce multiplie par 4 le temps d'exécution.

      • [^] # Re: Optimisation spécifique?

        Posté par  . Évalué à 4.

        Ce n'est une typo, 4.*i*i/(4.*i*i-1) est identique ou un poil plus lent que 4.*i*i/(4*i*i-1).

        Les mystères de l'optimisation des compilateurs m'étonneront toujours. Est-ce qu'il ne ferait pas le calcul en virgule flottante vs long int en fonction de la valeur de i?

  • # Pas très surprenant

    Posté par  (site web personnel, Mastodon) . Évalué à 7.

    Les engins JavaScript modernes sont des monstres d'optimisation JIT. Cette fonction est extrêmement simple et se compile très bien. Il n'y a aucun polymorphisme, aucune branche, juste une boucle et des calculs flottants.

    Il faut se garder d'en tirer des conclusions générales sur la performance de JavaScript, vu que la plupart du code réel ne passe pas la majorité de son temps dans des calculs numériques comme ça.

    Au passage, voici une manière de ramener le code Python au même ordre de grandeur de performance que C et JavaScript :

    import numpy
    
    WINDOW_SIZE = 10_000
    
    def wallis(n):
        a = 1.0
        for i in range(n//WINDOW_SIZE + 1):
            A = numpy.arange(i*WINDOW_SIZE + 1, min((i+1)*WINDOW_SIZE, n) + 1)
            B = 4.0*A**2
            C = B / (B-1)
            a *= C.prod()
        return a*2
    
    print(wallis(10**9))
  • # que dit le CPU(s) ?

    Posté par  . Évalué à 6.

    si ca se trouve ton code C tourne sur un seul CPU car tu ne lui dis pas de faire du multi coeur,
    et ton code javascript s'auto optimise pour tourner sur plusieurs coeurs, et te rendre les resultats ensuite

    sur une boucle de 1 à N avec 4 processeurs, tu aurais 25% de N sur chacun des processeurs,
    charge au programme en fin de boucle de regrouper les resultats

    je dis ca, je dis rien, j'ai pas testé,
    mais quand je faisais du C il fallait coder specialement pour lui dire de faire le multithread, là ou le JIT de javascript le fait peut-etre pour toi

    • [^] # Re: que dit le CPU(s) ?

      Posté par  . Évalué à 2.

      À ma connaissance, aucun runtime JS ne fait ce que tu décris.

      Et d'après mes tests, node 20 ne le fait pas:

      $ $TIME node wallis.js 
      45280,101%,2.08,2.04,0.07,0,48,470,0
      
      $ gcc -o wallis -O3 wallis.c ; $TIME ./wallis 
      1516,99%,1.84,1.84,0.00,0,13,1,0

      On vois que le JS comme le C n'utilisent qu'un seul CPU à 100% pendant environ 2s.

      IMHO l'explication c'est le JIT qui va transformer le JS en instructions natives et donc avec des performance comparable à la compilation AOT du C.

  • # Pas équivalent

    Posté par  . Évalué à 6.

    Tes deux implémentations ne sont pas équivalentes.

    Dans la version en javascript, tu appelle deux fois performance.now(), une fois en paramètre de console.log(), puis une autre fois après pour affecter t. Donc tu ne compte pas le temps passé à exécuter console.log()

    Dans la version en C, tu appelle une fois now() avant le printf, puis tu affecte la valeur obtenue à t. Donc ici le temps passé dans le printf est compté aussi.

    • [^] # Re: Pas équivalent

      Posté par  (site web personnel) . Évalué à 5.

      Tu as raison j'avais oublié !
      Du coup j'ai corrigé les 2 codes pour les rendre le plus proche possible, l'écart passe à 22% en faveur de C, c'est mieux même si ça ne change pas l'ordre de grandeur.

      • [^] # Re: Pas équivalent

        Posté par  . Évalué à 8.

        Intrigué par toute cette affaire, j'ai réalisé un petit benchmark avec mes gros doigts.

        J'y compare quatre implémentations ; celle en JavaScript, celles en C, celle en Python avec NumPy, et ma propre implémentation en Zig qui reprend celle en C.

        Pour exécuter Python, j'utilise Python 3.11.2. (Pypy dégrade les performances avec NumPy)
        Pour JavaScript, Bun 1.1.17 (plus performant que NodeJs).
        Pour la compilation du C et du Zig, Zig 0.13.0. (GCC donne les mêmes résultats)

        J'ai enlevé toutes les écritures dans la console sauf celui du résultat final, ainsi que les calculs de temps, pour éviter de pénaliser les langages qui sont plus lents à écrire ou à faire des appels systèmes.

        J'utilise l'outil hyperfine pour faire tourner le tout, et voilà le résultat :

        Command Mean [s] Min [s] Max [s] Relative
        python wallis.py 6.854 ± 0.055 6.808 6.960 1.84 ± 0.01
        bun wallis.js 3.733 ± 0.002 3.730 3.737 1.00 ± 0.00
        ./wallis_c 3.718 ± 0.001 3.717 3.720 1.00
        ./wallis_zig 3.718 ± 0.001 3.717 3.721 1.00 ± 0.00

        Bilan :

        Python est le plus lent, 1.84 fois plus lent que le plus rapide. Et ce, malgré l'utilisation de NumPy.
        JavaScript, grâce à Bun, est effectivement quasiment équivalent aux langages compilés, à moins d'un pourcent près.
        Les deux langages compilés sont équivalents, ce qui n'est guère surprenant.

        Le tout est disponible sur mon dépôt git si vous voulez faire tourner vous-même le benchmark ou prouver que votre langage est le meilleur : https://codeberg.org/alberic89/Wallis

        L'informatique n'est pas une science exacte, on n'est jamais à l'abri d'un succès

        • [^] # Re: Pas équivalent

          Posté par  (site web personnel) . Évalué à 5.

          Merci pour votre benchmark. Je vous en remercie.Mes résultats ont été très différents (la conclusion avec Zig vs GCC et la performance du Javascript que les autres langages).

          La compilation du C avec Zig (0.13.0) et GCC (14.1.1) ne donne pas les mêmes résultats.

          Command Mean [s] Min [s] Max [s] Relative
          ./wallis_gcc1 6.398 ± 0.060 6.336 6.543 1.00
          ./wallis_c 8.660 ± 0.061 8.605 8.797 1.35 ± 0.02
          ./wallis_gcc2 6.407 ± 0.081 6.337 6.568 1.00 ± 0.02

          La différence entre ./wallis_gcc1 et ./wallis_gcc2 est que j'utilise __builtin_expect pour la condition de if (n'est pas une bonne idée. Vous devez utiliser -fprofile-arcs à la place).

          $ diff wallis.c wallis_gcc.c
          20c20
          < if(i==b){
          ---
          > if(__builtin_expect(i==b, 0)){

          La différence entre la compilation de C avec Zig et GCC n'est pas petite.

          En Général:

          Command Mean [s] Min [s] Max [s] Relative
          bun wallis.js 10.271 ± 0.113 10.194 10.502 1.62 ± 0.03
          ./wallis_c 8.635 ± 0.033 8.609 8.711 1.36 ± 0.02
          ./wallis_zig 7.764 ± 0.038 7.743 7.848 1.22 ± 0.02
          ./wallis_gcc1 6.354 ± 0.022 6.340 6.397 1.00 ± 0.02
          ./wallis_gcc2 6.343 ± 0.108 6.101 6.560 1.00

          Je n'exécute pas Python. Javascript est le plus lent, 1.62 fois plus lent que le plus rapide.

          Mon Système:
          * Modèle du CPU: Intel i5-8365U CPU @ 1.60GHz
          * Taille de la mémoire RAM installée: 16Go
          * Système d'exploitation: Linux Fedora 40
          * Nombre de coeurs: 8

          Je pense que Javascript va faire plus similaire avec les autres langages compilés avec un bon ordinateur. Mais je pense,
          pour les ordinateurs plus vieux, la performance de Javascript va grandir que les autre langages compilés.

          p.s. Je suis désolé pour mon français. Maintenant, j'apprends le français pour le niveau A2 … Mon français n'est pas bien maintenant.

          • [^] # Re: Pas équivalent

            Posté par  . Évalué à 1.

            C'est drôle qu'il y ait autant d'écart !

            Pris d'un doute, j'ai relancé le benchmark, avec zig et gcc, en limitant la fréquence de mon CPU à 800MHz. J'ai bien vérifié qu'un seul cœur est utilisé. Voici mes résultats :

            Command Mean [s] Min [s] Max [s] Relative
            bun wallis.js 17.669 ± 0.003 17.664 17.672 1.00 ± 0.00
            ./wallis_gcc_c 17.624 ± 0.015 17.601 17.641 1.00 ± 0.00
            ./wallis_zig_c 17.613 ± 0.012 17.607 17.636 1.00 ± 0.00
            ./wallis_zig 17.609 ± 0.000 17.608 17.609 1.00

            wallis_gcc_c correspond au code C compilé avec GCC

            wallis_zig_c correspond au code C compilé avec Zig

            wallis_zig correspond au code Zig compilé avec Zig

            À presque rien près, j'ai le C avec le compilateur Zig plus rapide qu'avec GCC.

            Avez-vous bien désactivé toutes les écritures dans la console sauf la dernière ?

            Pour la compilation, j'ai utilisé les commandes suivantes :

            zig build-exe wallis.zig --name wallis_zig -O ReleaseFast
            zig cc wallis.c -o wallis_zig_c -O3
            gcc wallis.c -o wallis_gcc_c -O3

            Avez-vous utilisé les mêmes options d'optimisation ?

            Chez moi, JavaScript est toujours quasiment équivalent aux autres, même si un rien plus lent.

            Quelqu'un a-t-il d'autres résultats ?

            L'informatique n'est pas une science exacte, on n'est jamais à l'abri d'un succès

            • [^] # Re: Pas équivalent

              Posté par  (site web personnel) . Évalué à 1. Dernière modification le 29 juin 2024 à 21:19.

              Merci pour votre réponse. J'utilise les mêmes options d'optimisation.

              zig build-exe wallis.zig --name wallis_zig -O ReleaseFast
              zig cc wallis.c -o wallis_c -O3
              gcc wallis.c -o wallis_gcc1 -O3
              gcc wallis_gcc.c -o wallis_gcc2 -O3

              J'ai déconnecté mon compte sur l'ordinateur avant j'ai exécuté le benchmark. Mon console est la "seule" application fonctionnait (sauf les applications du système comme GUI (GNOME avec wayland) et processus en arrière-plan). Je n'ai pas changé votre code sauf ./wallis_gcc2.

              Les écritures dans la console, sauf la dernière, ont désactivé. Mais pour le Javascript, toutes les écritures ont désactivé.

              Voici les checksums pour les code sources (sauf ./wallis_gcc2):

              3ea4d6b73ab6e9719ee547fd29625e44 wallis.js
              e84fe29144ca7329e35aa1cc059a8bbb wallis.c
              7d66b54e15ce7ee93dda5c0fe4231941 wallis.zig

              Je vais réessayer dans mon ordinateur et dans un autre ordinateur. Votre nouveaux résultats pour Javascript est un grand surprise.
              C'est intéressant. Mais pour le Javascript, j'esperé qu'il n'est pas juste que le code n'est pas un écriture dans la console.

              Quelqu'un a-t-il d'autres résultats?

            • [^] # Re: Pas équivalent

              Posté par  (site web personnel) . Évalué à 1.

              Les résultats sont très intéressants. C'est très différent pour chaque système.

              Pour les résultats: https://codeberg.org/zakuArbor/Wallis/src/branch/master/results
              * laptop: ordinateur portable (Lenovo X1 Carbon Gen 7)
              * pc: petit ordinateur (Mini Desktop PC M900)
              * rpi3: Raspberry Pi 3
              * *-spec.md: les spécifications et les versions des compilateurs

              Les Résultats Sur l'Ordinateur Portable

              La poste dernière, j'ai utilisé mon ordinateur portable. J'ai relancé le benchmark et les résultats n'ont pas changé. Les résultats pour le deuxième fois sont ici

              Les Résultats Sur Le Petit Ordinateur

              Pour mon petit ordinateur (pc), la différence entre la compilation de C avec Zig et GCC n'est pas petite aussi.

              Command Mean [s] Min [s] Max [s] Relative
              ./wallis_gcc1 1.670 ± 0.010 1.653 1.682 1.00 ± 0.01
              ./wallis_c 2.257 ± 0.010 2.245 2.269 1.35 ± 0.01
              ./wallis_gcc2 1.666 ± 0.010 1.650 1.677 1.00

              Mais les résultats entre JavaScript et ./wallis_c (avec la compilation de Zig), c'était choquant.

              Command Mean [s] Min [s] Max [s] Relative
              bun wallis.js 2.096 ± 0.141 2.016 2.372 1.26 ± 0.08
              ./wallis_c 2.245 ± 0.018 2.218 2.262 1.35 ± 0.01

              Pour tous les résultats: https://codeberg.org/zakuArbor/Wallis/src/branch/master/results/pc/pc-result.md

              Spécs:
              * Modèle du CPU: Intel(R) Core(TM) i5-6500T CPU @ 2.50GHz
              * Taille de la mémoire RAM installée: 15Gi
              * Système d'exploitation: Fedora Linux 40 (Server Edition)
              * Nombre de coeurs: 4
              * Zig: 0.13.0
              * GCC: 14.1.1
              * Bun: 1.0.0

              Je ne comprends pas pourquoi ./wallis_c (avec la compilation de Zig) est plus lent. Si j'ai le temps, je vais analyser la performance avec perf et valgrind. La différence entre ./wallis_zig et JavaScript est petite, mais Zig est plus vite que Javascript. Il n'est pas surpris.

              Raspberry Pi 3

              J'ai obtenu les mêmes résultats avec votre CPU à 800MHz sur mon Raspberry Pi (à 1.2Ghz) pour la différence entre la compilation de C avec Zig et GCC.

              Command Mean [s] Min [s] Max [s] Relative
              ./wallis_gcc1 31.062 ± 0.002 31.058 31.065 1.00 ± 0.00
              ./wallis_c 31.062 ± 0.004 31.056 31.067 1.00 ± 0.00
              ./wallis_gcc2 31.061 ± 0.001 31.059 31.063 1.00

              Zig est le plus vite sur mon Raspberry Pi et JavaScript est le plus lent.

              Command Mean [s] Min [s] Max [s] Relative
              bun wallis.js 39.493 ± 0.003 39.490 39.499 1.43 ± 0.00
              ./wallis_c 31.031 ± 0.008 31.026 31.053 1.12 ± 0.00
              ./wallis_zig 27.674 ± 0.003 27.671 27.680 1.00
              ./wallis_gcc1 31.027 ± 0.002 31.026 31.030 1.12 ± 0.00
              ./wallis_gcc2 31.027 ± 0.002 31.026 31.032 1.12 ± 0.00

              Spécs:
              * Modèle du CPU: Cortex-A53
              * Taille de la mémoire RAM installée: 907Mi
              * Système d'exploitation: Debian GNU/Linux 12 (bookworm)
              * Nombre de coeurs: 4
              * Zig: 0.13.0
              * GCC: 12.2.0 (Il y a un problème avec mon script, j'ai écrit la version ici mais dans le répo, il n'y a pas la version)
              * Bun: 1.0.0

  • # Décalage binaire

    Posté par  . Évalué à 2.

    Quand i est un multiple de 2, l'élévation au carré peut-être effectuer par un simple décalage binaire plutôt qu'un multiplication.
    Le JIT de Javascript effectue peut-être cet optimisation alors que la compilation C non.

  • # Une autre piste

    Posté par  . Évalué à 3.

    As-tu comparé en C le i*i avec un pow(i*2) ?

    Car en javascript tu passe bien par une élévation de i au carré alors que tu fais une multiplication de i par i en C

    La fonction pow fait sans doute des optimisations, comme le fait sans doute l'utilisation de l'opérateur ** de javascript.

    • [^] # Re: Une autre piste

      Posté par  (site web personnel) . Évalué à 1.

      Testé à l'instant, hélas le pow(i*2) est un poil plus lent que i*i.

    • [^] # Re: Une autre piste

      Posté par  . Évalué à 2.

      La question n'est pas là. L'op s'attendait avec une implémentation naïve et similaire à un ordre de magnétude en faveur du C, car Javascript est dit interprété. Mais ce n'est pas vrai, JS dans Node et d'autres runtime est compilé par un JIT. Fin de l'histoire.

  • # Optimisations

    Posté par  (site web personnel) . Évalué à 3.

    Bonjour,

    J'ai fait quelques essais … en Perl (oui, c'est lent ;/) :
    my $n = 9;

    my $a = 2.0;
    my $min = 1;

    for (my $b=0 ; $b < $n ; $b++) {
    my $max = 10 * $min;
    for (my $i = $min; $i< $max; $i++) {
    $a += $a/(4*$i*$i - 1.);
    }
    $min = $max;
    print $b+1, " :\t", $a, "\n";
    }

    Double boucle : plutôt que tester un milliard de fois si  i est une puissance de 10,
    j'utilise des intervalles en progression géométrique de raison 10;

    Simplification de la formule de a en fonction de i : le multiplicateur B/(B-1)
    est arrangé en (D+1)/D = 1 + 1/D, un peu plus simple ; en outre, la multiplication  a *= (1+1/D ) peut être remplacée par une addition :  a += a/D

    La version additive tourne en 1mn 34.6s, et la multiplicative en 1mn 51.25s.

    Les résultats ne sont pas très bons : la boucle finale tourne 900 millions de fois
    pour rien (la 9ième valeur de a est identique à la précédente ; l'incrément devient beaucoup trop petit). Il faut donc utiliser des types plus longs pour les nombres obtenus.

    Autre amélioration possible : le calcul direct du dénominateur D en fonction de i
    peut être remplacé par un calcul itératif : on a un polynôme de degré 2 : P(X)= 4 * X² -1, et on utilise la méthode des différences finies :

    P(X+1) - (P(X) = 8 X + 4  = Q(X)

    Le terme constant -1 de D a disparu de la boucle (pour se cacher dans l'initialisation).

    On peut appliquer la même méthode à Q :

     R(X) = Q(X+1) - Q(X) = 8

    La différence théorique entre les sommes/produits partiels et la limite peut être évaluée à l'aide d'une intégrale : \int_N^{+\inf} dx/P(x)

  • # 90% des calculs ne servent à rien

    Posté par  . Évalué à 1.

    Bizarre ce programme quand même, le dernier bloc d'itérations n'améliore en rien l'évaluation de Pi. Si je ne me trompe pas, ce bloc (entre 10⁸ et 10⁹) représente 90% des itérations et du temps de calcul.
    On doit pouvoir faire beaucoup mieux comme test d'arrêt.

    • [^] # Re: 90% des calculs ne servent à rien

      Posté par  (site web personnel) . Évalué à 2.

      Oui ce n'est ni efficace ni précis, encore moins avec les limites physiques du codage interne des virgules flottantes et des entiers, de plus très vite le 4i²/(4i²-1) devient indiscernable de 1.

      C'est juste un classique du grand oral de bac, que j'ai pris comme prétexte vu sa petite taille et sa simplicité, pour ressortir le langage C et voir si JavaScript est réellement aussi optimisé qu'on le dit.

      Ce qui manifestement vrai, au moins là dessus, puisque je n'ai jamais dépassé les quelques % d'écart, ce qui ne manque pas de m'impressionner.

      Les dernières versions avec les remarques apportées ici par tous :

      Langage C :

      #include <stdio.h>
      #include <stdlib.h>
      #include <math.h>
      #include <time.h>
      
      double now(){
          struct timespec t;
          clock_gettime(CLOCK_MONOTONIC, &t);
          return t.tv_sec + t.tv_nsec /1000000000.;
      }
      
      
      double wallis(unsigned long n){
          double a = 2;
          unsigned long i = 1;
          double t = now();
          for(unsigned long b = 10; b<=n; b*=10){
              for(; i<=b ; i++){
                  a *= 4.*i*i/(4*i*i-1);
              }
              double t2 = now();
              printf("%.16f, time=%.3fs\n", a, (t2-t));
              t = t2;
          }
          return a;
      }
      
      int main(){
          printf("%.16f\n",wallis(pow(10,9)));
          return 0;
      }

      JavaScript :

      function wallis(n){
          let a=2.0;
          let i=1;
          let t = performance.now();
          for(let b=10; b<=n; b*=10){
              for(; i<=b ; i++){
                  a *= ((4.0*i**2)/(4*i**2-1));
              }
              let t2 = performance.now();
              console.log(a, ", time=", (t2-t)/1000.);
              t = t2;
          }
          return a;
      }
  • # Nice shot!

    Posté par  . Évalué à -4. Dernière modification le 29 juin 2024 à 17:39.

    Je suis 'stupé' + 'i' + 'fysé'

    Et pas loin de basculer sur "js(GNU/Linux)" si Rust ne gagne pas avec un petit "nice -20"!
    Quand même, il faudrait que vous trouviez une solution à ce détail:)

  • # Resolution futuriste

    Posté par  . Évalué à -8. Dernière modification le 29 juin 2024 à 18:03.

    #!usr/bin/env python2
    from __future__ import *
    
    from js import piPyPIpi
    from browser import facebook, facebook.lol
    
    if __name__ == '__main__':
        time_in = time.idontknow()
        browser = facebook.Browser(facebook.lol)
        browser.execute_js(piPyPIpi.wesh_man,msg = "perso", *["lol", "what's your icq # plz?"])
        time_out = time_in * 0
        print(f"time of execution: {time_out}")

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.