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

Collection et Stream Java Discussion :

Copie d'une collection dans un tableau


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 25
    Par défaut Copie d'une collection dans un tableau
    Bonjour,

    Lorsqu'on veut copier le contenu d'une liste (un java.util.ArrayList dans mon cas) dans un tableau, on peut utiliser la méthode "toArray", par exemple :
    J'ai pu constater que le toArray est beaucoup plus rapide à l'exécution (jusqu'à 10 fois plus rapide d'après mes tests) que d'utiliser une itération comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int index = 0;
    for ( T element : list )
        array[index++] = element;
    Mais maintenant, j'ai besoin de copier le contenu de la liste à un index dans le tableau qui n'est pas 0. C'est-à-dire que je veux faire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int index = startIndex;
    for ( T element : list )
        array[index++] = element;
    Depuis que j'ai constaté que le toArray est 10 fois plus rapide qu'une simple itération, je cherche comment je peux accélérer ce dernier cas !

    Des idées ?

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 25
    Par défaut Complément
    J'ai bien pensé à ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] tmp = list.toArray();
    System.arraycopy( tmp, 0, array, startIndex, list.size() );
    Manque de bol, l'allocation du tableau temporaire "tmp" et sa recopie font perdre tout l'intérêt du toArray en terme de vitesse d'exécution !

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 25
    Par défaut Exemple de programme de test
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    package perf;
     
    import java.util.ArrayList;
    import java.util.List;
     
    public class PerfToArray
    {
    	private static int repeat = 10000;
    	private static int nbOfString = 10000;
    	private static List<String> list = new ArrayList<String>( nbOfString );
    	private static String[] array = new String[nbOfString];
     
    	public static void main( String[] args )
    	{
    		for ( int i = 0; i < nbOfString; i++ )
    			list.add( String.valueOf(i) );
     
    		long time_1 = copy1( repeat, list, array );
     
    		System.out.println( "Copie avec toArray = "+ time_1 +" ms" );
     
    		long time_2 = copy2( repeat, list, array );
     
    		System.out.println( "Copie avec Iterator = "+ time_2 +" ms" );
    	}
     
    	private static <T> long copy1( int repeat, List<T> list, T[] array )
    	{
    		long start = System.currentTimeMillis();
     
    		while ( repeat-- > 0 )
    			list.toArray( array );
     
    		long stop = System.currentTimeMillis();
     
    		return stop-start;
    	}
     
    	private static <T> long copy2( int repeat, List<T> list, T[] array )
    	{
    		long start = System.currentTimeMillis();
     
    		while ( repeat-- > 0 )
    		{
    			int index = 0;
    			for ( T element : list )
    				array[index++] = element;
    		}
     
    		long stop = System.currentTimeMillis();
     
    		return stop-start;
    	}
    }
    C:\hlb\Java>java -version
    java version "1.6.0_24"
    Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
    Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)

    C:\hlb\Java>java perf.PerfToArray
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4375 ms

    C:\hlb\Java>

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    On sait. C'est parce que ArrayList fonctionne en maintenant un Object[] en interne, et donc qu'il peut lui-même faire System.arraycopy() quand on lui demande un toArray().
    Avec un LinkedList, par exemple, toArray() se fait dans le même temps qu'une boucle, puisque c'est une boucle.

    Bon, pour ce que tu veux faire : le mieux est de ne pas avoir besoin d'insérer à un index précis d'un tableau. Tu es programmeur, non ? Il est assez rare que ce genre de contraintes soient justifiées. Principalement, les tableaux ne sont pas très souples, c'est dans leur nature, alors pourquoi passer par eux s'ils nous embêtent au lieu de nous aider ?

    Si tu y tiens quand même, il y a moyen d'économiser un peu de temps :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    String[] array = new String[tailleDuTableauFinalPasDeLaListe];
    // La liste a été insérée au début du tableau.
    list.toArray(array);
    // Décalage rapide du contenu du tableau
    System.arrayCopy(array, 0, array, indexVoulu, list.size());
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 25
    Par défaut
    Merci ... mais je ne peux pas utiliser cette technique.

    Je dois copier des données provenant d'un ArrayList que j'ai rempli dans un tableau qui m'est passé et à un index qui m'est imposé. Je n'ai pas le droit d'écraser les éléments qui précèdent dans le tableau qu'on me passe. Ce n'est pas moi qui alloue le tableau.

    Domage que ArrayList n'ai pas de méthode toArray( T[] array, int toIndex ) pour copier dans le tableau à l'index toIndex ! Ca permettrait une copie rapide.

    La solution consistera peut-être pour moi abandonner ArrayList au profit d'autre chose. Je réfléchi ...

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Vous êtes typiquement dans le cas d'erreur d'optimisation hâtive, un cas formidable (j'ai envie d'épingler le sujet pour le coup, un beau cas d'école).

    1) votre protocole de mesure est incorrect. Pour avoir le temps réel, il faut laisser le temps au compilateur JIT de "chauffer" pour qu'il fasse sa compilation native sur les points chauds. Une seule mesure ne suffit pas. Le compilateur JIT, il est pas con, il va pas optimiser des trucs qui ne servent pas souvent. Souvent pour lui, c'est plus que 10.000
    2) Vous mesurez deux manières de faire un tout petit élément de code sans savoir si ce petit élément de code en vaut la peine -> Vous devez faire un profiling de votre application réelle.
    3) vous devez multiplier les mesures et les comparer.

    Je vois déjà une bourde bien belle sans même lancer le code: vous ne comparez pas la différence entre les deux types de copie avec le temps nécessaire pour créer la ArrayList. A quoi vous sert de gagner 0.35ms sur la copie tableau à un index précis d'une liste de 10.000 éléments, si la création de cette liste prend déjà 1.5ms (et je ne parle pas de tous l'éventuel traitement de données pour créer les données avant de les mettres dans la liste, juste leur insertion). Bref, vous essayez de faire gagner 70% de temps de calcul à une opération qui doit représenter en elle même moins de 1% de votre temps de calcul. Au mieux vous allez améliorer votre algorithme de 0.7%!

    Bon maintenant, la démonstration. Soit votre code légèrement modifié:
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    package perf;
     
    import java.util.ArrayList;
    import java.util.List;
     
    public class PerfToArray
    {
    	private static int repeat = 10000;
    	private static int nbOfString = 10000;
    	private static List<String> list = new ArrayList<String>( nbOfString );
    	private static String[] array = new String[nbOfString];
     
    	public static void main( String[] args )
    	{
               while(true){
                    long a = System.currentTimeMillis();
                    for (int j=0; j< repeat; j++){
                      list = new ArrayList<String>( nbOfString );
    		  for ( int i = 0; i < nbOfString; i++ )
    			list.add( String.valueOf(i) );
                    }
    		System.out.println( "Creation de liste "+ (System.currentTimeMillis()-a) +" ms" );
     
    		long time_1 = copy1( repeat, list, array );
     
    		System.out.println( "Copie avec toArray = "+ time_1 +" ms" );
     
    		long time_2 = copy2( repeat, list, array );
     
    		System.out.println( "Copie avec Iterator = "+ time_2 +" ms" );
               }
    	}
     
    	private static <T> long copy1( int repeat, List<T> list, T[] array )
    	{
    		long start = System.currentTimeMillis();
     
    		while ( repeat-- > 0 )
    			list.toArray( array );
     
    		long stop = System.currentTimeMillis();
     
    		return stop-start;
    	}
     
    	private static <T> long copy2( int repeat, List<T> list, T[] array )
    	{
    		long start = System.currentTimeMillis();
     
    		while ( repeat-- > 0 )
    		{
    			int index = 0;
    			for ( T element : list )
    				array[index++] = element;
    		}
     
    		long stop = System.currentTimeMillis();
     
    		return stop-start;
    	}
    }
    J'ai simplement ajouté un while pour faire plusieurs mesures, et la même boucle de 10.000 repeat pour créer la liste 10.000 fois (histoire de comparer ce qui est comparable).

    Ma version java:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    java version "1.6.0_12"
    Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
    Java HotSpot(TM) Server VM (build 11.2-b01, mixed mode)
    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
    29
    30
    31
    32
     
    tchize@aspirine-duo:/tmp$ ~/apps/jdk1.6.0_12/bin/java perf.PerfToArray 
    Creation de liste 5815 ms
    Copie avec toArray = 455 ms
    Copie avec Iterator = 1828 ms
    Creation de liste 5927 ms
    Copie avec toArray = 297 ms
    Copie avec Iterator = 1793 ms
    Creation de liste 5901 ms
    Copie avec toArray = 295 ms
    Copie avec Iterator = 1797 ms
    Creation de liste 5915 ms
    Copie avec toArray = 301 ms
    Copie avec Iterator = 477 ms
    Creation de liste 5956 ms
    Copie avec toArray = 297 ms
    Copie avec Iterator = 463 ms
    Creation de liste 5911 ms
    Copie avec toArray = 300 ms
    Copie avec Iterator = 464 ms
    Creation de liste 5911 ms
    Copie avec toArray = 295 ms
    Copie avec Iterator = 471 ms
    Creation de liste 5908 ms
    Copie avec toArray = 294 ms
    Copie avec Iterator = 466 ms
    Creation de liste 5913 ms
    Copie avec toArray = 294 ms
    Copie avec Iterator = 466 ms
    Creation de liste 5925 ms
    Copie avec toArray = 295 ms
    Copie avec Iterator = 467 ms
    Comme vous voyez, une fois "chaud", 10.000 Liste -> array par itération, représentent moins de 10% de "créer 10.000 listes". De plus, les temps de copie se sont fortement rapprochés et améliorés.

    Bref les point important:
    -> n'optimisez pas inutilement au départ (j'ai pas dit non plus faites des algorithmes de cochon hein )
    -> utilisez un profiler pour identifier les points chauds de l'application une fois celle-ci fonctionnelle
    -> faites de nombreuses mesures qui se corroborent, chaque fois sur une période de temps représentative de la durée de fonctionnement de l'application (et pas un run de 15 secondes)
    -> Regardez comment vous pouvez otpimiser les point chauds le plus importants (ceux où votre application passe 10% du temps ou plus).

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 25
    Par défaut
    De manière générale, je suis tout à fait d'accord avec votre développement. Je suis conscient des questions que vous soulevez et elles relèvent d'un parfait bon sens et en même temps elles dénotent une réelle expérience de la programmation de votre part.

    Sans vouloir tirer la couverture à moi, j'ose dire que j'étais conscient de ce que vous indiquez avant de poster et même depuis fort longtemps.

    Néanmoins, je me permet de faire trois remarques sur vos remarques:

    Remarque 1/

    Vous ne savez pas comment je rempli l'ArrayList dans mon appli réelle. Ce que j'ai mis au début, un "String.valueOf( i )" qui fait une allocation de String à chaque itération n'est pas la réalité. Or, vous le reprenez dans votre évaluation de temps globale.

    Remarque 2/

    Vous dites que je n'ai pas laissé le temps au JIT de chauffer. C'est peut-être le cas, mais ce point là, vous ne le démontrez pas. Je veux dire que vous n'avez pas montré que les temps obtenus sur mon test sont faux. Vous dites juste qu'ils peuvent être faux ... ce que je ne peux pas nier absolument.

    Je sais bien que le micro-benchmarking est très dangeureux à bien des égards. Mais, c'est une chose d'affirmer cela et c'est une autre de prouver que le cas d'espèce est incorrect.

    Pour communiquer dans un forum, un petit bout de code c'est tout de même plus pratique que de copier-coller un "dump" de profiler !

    Remarque 3/

    Mon point concernait uniquement la copie d'une liste dans un tableau à un index donné. En rappelant des généralités -très pertinentes au demeurant- vous ne répondez pas à ma question initiale.

    Je vais continuer à chercher même si vous pensez que c'est inutile !

  8. #8
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par hlbnet Voir le message
    Vous ne savez pas comment je rempli l'ArrayList dans mon appli réelle. Ce que j'ai mis au début, un "String.valueOf( i )" qui fait une allocation de String à chaque itération n'est pas la réalité. Or, vous le reprenez dans votre évaluation de temps globale.
    Si je retire le valueof (en mettant la même constante "hello" partout), je passe à ~1000 ms pour créer la liste contre ~370 pour la transférer via l'itérator, le remplissage reste le point chaud.
    Vous dites que je n'ai pas laissé le temps au JIT de chauffer. C'est peut-être le cas, mais ce point là, vous ne le démontrez pas.
    Ma sortie pourtant le démontre: il faut le temps pour que les choses se mettent en place.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Creation de liste 5815 ms
    Copie avec toArray = 455 ms
    Copie avec Iterator = 1828 ms
    Creation de liste 5927 ms
    Copie avec toArray = 297 ms
    Copie avec Iterator = 1793 ms
    Creation de liste 5901 ms
    Copie avec toArray = 295 ms
    Copie avec Iterator = 1797 ms
    Creation de liste 5915 ms
    Copie avec toArray = 301 ms
    Copie avec Iterator = 477 ms
    Le compilateur JIT utilise des heuristiques, il est imprévisible. D'une machine à l'autre et même d'une exécution à l'autre, il peut optimiser différents bout de code. C'est pour ça que pour tout benchmark, il faut
    -> mesurer le temps intégral qu'a pris l'application si le but de l'application est de travailelr en "one shot"
    -> Laisser l'application tourner quelque temps avant de brancher le profiler si l'application est une application serveur destinée à tourner en continu ou sur une période de temps de plus que quelques minutes.
    -> Multiplier les mesures sur plusieurs run.

    Remarque 3/

    Mon point concernait uniquement la copie d'une liste dans un tableau à un index donné. En rappelant des généralités -très pertinentes au demeurant- vous ne répondez pas à ma question initiale.
    Si vous venez pour juste une réponse à ce point, elle tiens en une ligne
    -> Ca n'existe pas
    (et ça n'aurait aucun sens d'exister, List est une interface, ArrayList n'est qu'un cas particulier de cette interface)

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 25
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Si vous venez pour juste une réponse à ce point, elle tiens en une ligne
    -> Ca n'existe pas
    (et ça n'aurait aucun sens d'exister, List est une interface, ArrayList n'est qu'un cas particulier de cette interface)
    Je sais bien que d'avoir un toArray( T[] array, int toIndex ) dans Collection<T>, ça ne révolutionnerai pas les collections Java !
    Mais, dire que ça n'aurait aucun sens, je trouve que vous y allez un peu fort.

    D'ailleurs, je viens de jeter un oeil à l'implémentation de ArrayList et je vois ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
         public boolean  addAll(Collection<? extends E> c) {
             Object[] a = c.toArray();
             int numNew = a.length;
             ensureCapacity(size + numNew);  // Increments modCount
             System.arraycopy(a, 0, elementData, size, numNew);
             size += numNew;
             return numNew != 0;
         }
    Je vois qu'au lieu d'iterer directement sur la collection passée, il y a passage par un tableau temporaire, puis recopie du contenu de celui-ci dans le tableau d'arrivée.

    Puisqu'ils font comme ça dans ArrayList, je pense que je vais faire pareil. Mais je ne peux pas m'empêcher de penser que s'il y avait eut un toArray( T[] array, int toIndex ) dans Collection<T> ils l'auraient utilisé ce qui aurait permis d'éliminer quelques étapes (allocation+copie). Je sais, rien de révolutionnaire !

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 25
    Par défaut
    Pour info, lorsqu'on met les copies dans un while (true) pour faire chauffer le JIT, on obtiens:
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4438 ms
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4438 ms
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4094 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4094 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4093 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4094 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4109 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4094 ms
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4094 ms
    Copie avec toArray = 438 ms
    Copie avec Iterator = 4172 ms
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4078 ms
    Copie avec toArray = 438 ms
    Copie avec Iterator = 4093 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4094 ms
    Copie avec toArray = 438 ms
    Copie avec Iterator = 4093 ms
    Copie avec toArray = 438 ms
    Copie avec Iterator = 4094 ms
    Copie avec toArray = 421 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 407 ms
    Copie avec Iterator = 4140 ms
    Copie avec toArray = 407 ms
    Copie avec Iterator = 4140 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4141 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4141 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4187 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4157 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4141 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4141 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4156 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4141 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4203 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4141 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4141 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4219 ms
    Copie avec toArray = 421 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 407 ms
    Copie avec Iterator = 4156 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4156 ms
    Copie avec toArray = 407 ms
    Copie avec Iterator = 4218 ms
    Copie avec toArray = 407 ms
    Copie avec Iterator = 4172 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4156 ms
    Copie avec toArray = 406 ms
    Copie avec Iterator = 4157 ms
    Copie avec toArray = 421 ms
    Copie avec Iterator = 4157 ms
    Copie avec toArray = 406 ms

    Je ne veux pas défendre ce micro-bench bec et ongle, je sais que c'est toujours limité comme résultat (ça dépend de la JVM aussi !)

    Mais bon, je pense que mon test n'est pas manifestement faux.
    Ce qui n'enlève rien à la pertinence de vos remarques ... ni à celle de ma question initiale !

  11. #11
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    tchize_ a raison ! Il faut toujours se méfier des microbenchmarks !


    Perso je suis en 64 bits avec une JVM server, et j'obtiens le résultat inverse : que dois-je en conclure ???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    java -showversion PerfToArray
     
    java version "1.6.0_23"
    Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
    Java HotSpot(TM) 64-Bit Server VM (build 19.0-b09, mixed mode)
     
    Copie avec toArray = 506 ms
    Copie avec Iterator = 395 ms
    Je n'ai pas pu tester avec la JVM client : elle n'existe pas en 64 bits...




    Par curiosité modifie ta méthode main() de cette manière :

    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
    	public static void main(String[] args) {
     
    		for (int i = 0; i < nbOfString; i++)
    			list.add(String.valueOf(i));
     
    		for (int i=0; i<5; i++) {
    			System.out.print("Copie avec toArray  = ");
    			long time_1 = copy1(repeat, list, array);
    			System.out.println(time_1 + " ms");
     
    			System.out.print("Copie avec Iterator = ");
    			long time_2 = copy2(repeat, list, array);
    			System.out.println(time_2 + " ms");
    		}
    	}
    Et lances ton code avec l'option -verbose:gc



    a++

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 25
    Par défaut Avec -verbose:gc
    C:\hlb\Java>java -verbose:gc -jar PerfToArray.jar
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4469 ms
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4469 ms
    Copie avec toArray = 438 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4203 ms
    Copie avec toArray = 438 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4140 ms
    Copie avec toArray = 438 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4110 ms
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 438 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 422 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 437 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 438 ms
    Copie avec Iterator = 4125 ms
    Copie avec toArray = 421 ms

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 25
    Par défaut
    adiGuba,

    Ca m'intrigue un peu que sur ta machine ça soit l'inverse, même si je sais bien que les micro-benchmark sont toujours tendencieux.

    Juste pour fixer les idées, j'aimerais que tu essaie avec un "repeat" plus grand vu que tu as une machine visiblement plus puissante.

    Multiplie au moins par 10 le repeat et réessaie.

  14. #14
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    C'est surtout que ton test est faussé à cause de la compilation à la volé. C'est pourquoi il faut faire plusieurs essai : les premiers résultats sont faussé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Copie avec toArray  = 506 ms
    Copie avec Iterator = 402 ms
    Copie avec toArray  = 217 ms
    Copie avec Iterator = 372 ms
    Copie avec toArray  = 217 ms
    Copie avec Iterator = 254 ms
    Copie avec toArray  = 216 ms
    Copie avec Iterator = 254 ms
    Copie avec toArray  = 217 ms
    Copie avec Iterator = 254 ms
    Au bout d'un moment cela se stabilise entre 217ms et 254ms. Ces chiffres sont plus cohérent


    Si j'augmente le nombre de repeat, les résultats se stabilisent dans les mêmes proportions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Copie avec toArray  = 2170 ms
    Copie avec Iterator = 2550 ms


    Les premiers résultats ne sont pas fiables car ils sont faussé par la compilation hotspot (on peut vérifier cela avec l'option -XX:+PrintCompilation). C'est pour éviter cela qu'il faut effectuer plusieurs fois les mêmes tests...


    C'est d'autant plus vrai avec la JVM client qui tarde un peu à effectuer les optimisations.


    D'ailleurs si tu as vraiment besoin de performance, la première démarche serait d'utiliser une JVM server...


    a++

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

Discussions similaires

  1. [Tableaux] Recherche d'une chaine dans un tableau
    Par tom06440 dans le forum Langage
    Réponses: 5
    Dernier message: 20/10/2005, 23h27
  2. [HTML] Charger une page dans un tableau? Possible?
    Par mec.nimois dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 17/10/2005, 11h32
  3. ligne blanche sous une image dans un tableau
    Par spikelille dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 10/09/2005, 18h24
  4. [JTable] Afficher une date dans un tableau / Renderer
    Par isak dans le forum Composants
    Réponses: 3
    Dernier message: 11/07/2005, 17h09
  5. probleme bizarre de hauteur auto d'une ligne dans un tableau
    Par zax-tfh dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 17/01/2005, 23h34

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