0
votes

Quelle boucle est plus efficace?

Je veux savoir quel code est plus efficace et j'ai deux options. Que diriez-vous qu'il est plus efficace et pourquoi? Merci.

option A fort> p> xxx pré>

Option B forte> p>

array1 size is 1000
array2 size is 2000


    for(int i = 0; i < array1.size(); i++)
    {
        for(int j = 0; j < array2.size(); j++) {
            if(array1[i].method() == array2[j].method()) // CHECKS IF THERE'S AN EQUAL IN BOTH ARRAYS
            {
                doSomething();
                break;
            }
            if(j == array2.size-1)  // CHECKS IF ARRAY1 HAS NO ARRAY2 MATCH
            {
                doSomething();
                break;
            }
        }
    }

    for(int j = 0; j < array2.size(); j++)
    {
        for(int i = 0; i < array1.size(); i++) {
            if(array2[j].method() == array1[i].method()) // CHECKS IF THERE'S AN EQUAL IN BOTH ARRAYS
            {
                // BUT DOES NOTHING BECAUSE IT WAS DONE ALREADY UPSIDE
                break;
            }
            if(i == array1.size-1) // CHECKS IF ARRAY2 HAS NO ARRAY1 MATCH
            {
                doSomething();
                break;
            }
        }
    }


3 Réponses :


1
votes

option A est O (x ^ 2 * y) Option B est O (x * y) Dans votre option de cas, une itération prendra jusqu'à 2 000 000 000 itérations alors que B prendra jusqu'à 4 000 000 itérations. Cela n'inclut pas les pauses ou continue bien sûr. Je serais probablement coller avec b.


1 commentaires

Merci. C'est la bonne réponse. L'option A a pris 30 minutes pour ma boucle et l'option B a pris 3 secondes.



1
votes

Comme indiqué par @ sploder12 mais vous gagnerez également beaucoup de manière à supprimer les appels de fonction dans la boucle par exemple. xxx

plutôt que xxx

sauf si vous modifiez la taille de la matrice dans la boucle, les appels de fonction répétés sont un gaspillage.


2 commentaires

Votre suggestion a amélioré le temps de l'heure écoulée: 2.6623344 au temps écoulé: 1.9251856. Agréable!


On n'imposerait pas à ce niveau. La JVM devrait être en mesure de noter que la taille est efficace et la substitue. Dès que le code est chaud, cette optimisation doit être effectuée automatiquement.



0
votes

En ce qui concerne le commentaire de @ Turing85, je me suis demandé s'il peut exister ou non un mécanisme de compilateur qui pourrait repérer le fait que la valeur de retour de la taille () dans les initialisations de boucle peut être constante et pourrait donc être remplacée par une constante " définitif efficacement ". J'ai donc couru les deux boucles suivantes, la première sans l'optimisation constante manuelle: xxx

la seconde avec une optimisation constante manuelle: xxx

J'ai ensuite couru ces boucles 10 fois avec A1.Size () = 100, A2.Size () = 200, et A3.Size () = 300 pour obtenir une heure et calculé l'erreur moyenne et standard de 100 fois pour chaque variante de La boucle avec l'ordre des 200 pistes randomisées.

Tout ce processus a été répété 10 fois dans un seul travail (c'est-à-dire une seule invocation de la JVM) pour obtenir 10 moyennes jumelées et erreurs standard (un membre de la paire des courses optimisées et l'autre de la pistes non optimisées). Dans les 10 cas, les temps moyens optimisés étaient considérablement plus rapides que les temps moyens non optimisés. Dans tous les cas, la différence entre les moyens était supérieure à 6,9 fois l'erreur standard et dans 7 des 10 cas, la différence entre les moyens était supérieure à 15 erreurs standard. Les données sont données ci-dessous. Le code d'octet généré pour les boucles était différent et, bien que je ne prétends pas parler de bytecode, des appels invoquionnaires supplémentaires ont été des appels invoqués supplémentaires à un * .Size () que je suppose sont responsables des différences dans la performance des deux versions de boucle.

Donc, en tenant compte du commentaire de @ Turing85, je m'interroge sur les conditions dans lesquelles des optimisations "à ce niveau" peuvent être ignorées?

Version OpenJDK "11" 2018-09-25 OpenJDK Runtime Environment 18.9 (Build 11 + 28) OpenJDK 64 bit Server VM 18.9 (Build 11 + 28, mode mixte)

====== Data ======

100 courses de boucle optimisée a pris moyenne 6,412s chacune, erreur standard 0,013; 100 Les courses de boucle non optimisée ont pris en moyenne 6.502s chacune, erreur standard 0.013

100 exécutions de boucle optimisée a pris en moyenne 5,143s chacun, erreur standard 0,004; 100 Les courses de boucle non optimisée ont pris en moyenne 5,232s chacune, erreur standard 0.005

100 exécutions de boucle optimisée prises en moyenne 6.090S chacune, erreur standard 0,006; 100 Les courses de boucle non optimisée ont pris en moyenne 6.175s chacune, erreur standard 0.006

100 exécutions de boucle optimisée a pris en moyenne 5,739s chacun, erreur standard 0,005; 100 Les courses de boucle non optimisée ont pris en moyenne 5,827s chacune, erreur standard 0.005

100 exécutions de boucle optimisée a pris en moyenne 5,613s chacun, erreur standard 0,005; 100 Les courses de boucle non optimisée ont pris en moyenne 5,697s chacune, erreur standard 0.004

100 exécutions de boucle optimisée prises en moyenne 6,045s chacune, erreur standard 0,004; 100 points de boucle non optimisée ont pris en moyenne 6.121s chacun, erreur standard 0.004

100 exécutions de boucle optimisée prises en moyenne 5,333s chacune, erreur standard 0,003; 100 Les courses de boucle non optimisée ont pris en moyenne 5,415s chacune, erreur standard 0.003

100 exécutions de boucle optimisée a pris en moyenne 5,903s chacun, erreur standard 0,009; 100 Les courses de boucle non optimisée ont pris en moyenne 5,972s chacune, erreur standard 0.007

100 exécutions de boucle optimisée prises en moyenne 5,770s chacune, erreur standard 0,005; 100 Les courses de boucle non optimisée ont pris en moyenne 5,851s chacune, erreur standard 0.005

100 exécutions de boucle optimisée ont pris en moyenne 4,975s chacun, erreur standard 0,004; 100 Les courses de boucle non optimisée ont pris en moyenne 5,052s chacun, erreur standard 0,004


1 commentaires

Merci beaucoup pour votre réponse. Vous avez fait un test avec de très petites tailles; Faites de même lorsque les tailles de chaque boucle sont plus grandes. La différence va être énorme. Ajouter à la comparaison selon laquelle ArrayList.Size () pourrait être plus inefficace que d'autres types de dimensionnement.