8 votes

Meilleure pratique de Java for-loop

Quelle est la meilleure façon de boucler un tableau lorsque vous avez besoin de l'index ?

Option 1 :

int len = array.length;
for (int i = 0; i < len; ++i) {
    array[i] = foo(i);
}

Option 2 :

for (int i = 0; i < array.length; i++) {
    array[i] = foo(i);
}

Ou bien, cela n'a-t-il pas d'importance ? Ou y a-t-il une meilleure façon de procéder ? Juste pour souligner les différences : Dans un cas, la longueur du tableau est évaluée dans le cadre du test dans la boucle, bien que le compilateur doive normalement optimiser cela.


Deuxièmement, est-ce que ++i n'est pas différent ici de i++ ? Je préfère nettement ++i si c'est C++ mais je ne suis pas sûr pour Java.

6voto

Dan Points 7970

i++ vs ++i n'a pas d'importance dans ce cas particulier. Alors que les maîtres du C vous diront de stocker array.length dans une variable, les compilateurs d'optimisation modernes rendent cela inutile dans ce cas, tant que la longueur ne change pas dans la boucle. Si vous êtes vraiment inquiet, vous pouvez évaluer les deux, mais étant donné que .length n'a pas besoin de parcourir l'ensemble du tableau à chaque fois, tout va bien.

6voto

arshajii Points 65653

En général, ces deux méthodes sont équivalentes. Vous devez noter que dans

for (int i = 0 ; i < foo() ; i++) {
    ...
}

le site foo() est appelé une fois avant chaque itération (par opposition à une seule fois avant la première itération), vous voudrez peut-être prendre cela en compte pour des situations plus compliquées en faisant quelque chose comme

int n = foo();
for (int i = 0 ; i < n ; i++) {
    ...
}

qui est analogue à votre Option 1 . Je dirais donc Option 1 est certainement le plus sûr des deux, mais la plupart du temps, il ne devrait pas y avoir de différence significative entre les deux.


Quant à votre deuxième question : ++i incrémente d'abord votre variable et récupère ensuite sa valeur, i++ récupère d'abord la valeur, puis l'incrémente. Essayez ces deux morceaux de code :

int i = 0;
System.out.println(++i);
------------------------
int i = 0;
System.out.println(i++);

Les premières impressions 1 mais le second imprime 0 . Bien sûr, lorsque ++i y i++ sont seuls, cela ne fait aucune différence.

0voto

user1107832 Points 1

Pour savoir s'il faut utiliser "array.length" dans la boucle for : Généralement le compilateur fera une certaine optimisation, par conséquent, il est équivalent d'utiliser une variable dans la boucle for.

pour "i++" et "++i". En C++, ++i est préférable et plus efficace, mais en Java, ils sont équivalents dans ce cas.

0voto

Ced Points 6385

En plus de la réponse d'arshaji, je voulais savoir s'il y avait un avantage en termes de performance à utiliser size() dans une boucle plutôt que de le stocker à l'avance. Je pense que le résultat montre que le compilateur optimise les choses et que l'accès à la longueur d'une liste est identique à l'accès à une variable (je craignais que le fait de devoir passer par une fonction ne ralentisse les choses).

Voici le temps qu'il faut pour les deux pour différentes méthodes de boucle :

for(long i = 0 ; i < mylist.size(); i++){}
VS
for(long i = 0 ; i < 10_000_000; i++){}

Voici le résultat pour une liste de dix millions d'éléments :

fixed length:
,162,157,151,157,156,159,157,149,150,170,158,153,152,158,151,151,156,156,151,153
getSize:
,164,156,159,154,151,160,162,152,154,152,151,149,168,156,152,150,157,150,156,157

import java.util.ArrayList;
import java.util.List;

public class Main {

    final static int LENGTH_SAMPLE = 20;
    final static long LENGTH = 10_000_000;

    public static void main(String[] args) {

        List<Long> mylist = new ArrayList<>();
        for(long i = 0 ; i < LENGTH; i++){
            mylist.add(i);
        }
        System.out.println("fixed length:");
        for(int i = 0 ; i < LENGTH_SAMPLE; i++){
            System.out.printf("," + fixedSize(mylist));
        }
        System.out.println("");
        System.out.println("getSize:");
        for(int i = 0 ; i < LENGTH_SAMPLE; i++){
            System.out.printf("," + fctSize(mylist));
        }
    }

    private static long fixedSize(List list){
        long start = System.currentTimeMillis();

        for(long i = 0 ; i < LENGTH; i++){
            System.currentTimeMillis();
        }
        return System.currentTimeMillis() - start;
    }

    private static long fctSize(List list){
        long start = System.currentTimeMillis();

        for(long i = 0 ; i < list.size(); i++){
            System.currentTimeMillis();
        }
        return System.currentTimeMillis() - start;
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X