java d'objet initialiser - Vaut-il mieux utiliser System.arraycopy (...) qu'une boucle for pour copier des tableaux?




4 Answers

public void testHardCopyBytes()
{
    byte[] bytes = new byte[0x5000000]; /*~83mb buffer*/
    byte[] out = new byte[bytes.length];
    for(int i = 0; i < out.length; i++)
    {
        out[i] = bytes[i];
    }
}

public void testArrayCopyBytes()
{
    byte[] bytes = new byte[0x5000000]; /*~83mb buffer*/
    byte[] out = new byte[bytes.length];
    System.arraycopy(bytes, 0, out, 0, out.length);
}

Je sais que les tests JUnit ne sont pas vraiment les meilleurs pour l'analyse comparative, mais
testHardCopyBytes a pris 0.157s pour terminer
et
testArrayCopyBytes a pris 0.086s pour terminer.

Je pense que cela dépend de la machine virtuelle, mais il semble que cela copie des blocs de mémoire au lieu de copier des éléments d'un seul tableau. Cela augmenterait absolument les performances.

MODIFIER:
Il semble que les performances de System.arraycopy soient partout. Lorsque les chaînes sont utilisées à la place des octets et que les tableaux sont petits (taille 10), j'obtiens les résultats suivants:

    String HC:  60306 ns
    String AC:  4812 ns
    byte HC:    4490 ns
    byte AC:    9945 ns

Voici à quoi cela ressemble quand les tableaux sont à la taille 0x1000000. Il semble que System.arraycopy gagne définitivement avec des tableaux plus grands.

    Strs HC:  51730575 ns
    Strs AC:  24033154 ns
    Bytes HC: 28521827 ns
    Bytes AC: 5264961 ns

Comment particulier!

Merci, Daren, de souligner que les références copient différemment. Cela en a fait un problème beaucoup plus intéressant!

remplir clone

Je veux créer un nouveau tableau d'objets en assemblant deux tableaux plus petits.

Ils ne peuvent pas être NULL, mais la taille peut être 0.

Je ne peux pas choisir entre ces deux façons: sont-ils équivalents ou sont-ils plus efficaces (par exemple, system.arraycopy () copie des morceaux entiers)?

MyObject[] things = new MyObject[publicThings.length+privateThings.length];
System.arraycopy(publicThings, 0, things, 0, publicThings.length);
System.arraycopy(privateThings, 0, things,  publicThings.length, privateThings.length);

ou

MyObject[] things = new MyObject[publicThings.length+privateThings.length];
for (int i = 0; i < things.length; i++) {
    if (i<publicThings.length){
        things[i] = publicThings[i]
    } else {
        things[i] = privateThings[i-publicThings.length]        
    }
}

La seule différence est-elle l'apparence du code?

EDIT: merci pour la question liée, mais ils semblent avoir une discussion non résolue:

Est-ce vraiment plus rapide si it is not for native types : byte [], Object [], char []? dans tous les autres cas, une vérification de type est exécutée, ce qui serait mon cas et serait donc équivalent ... non?

Sur une autre question liée, ils disent que the size matters a lot , pour une taille> 24 system.arraycopy () gagne, pour moins de 10, manuel pour la boucle est mieux ...

Maintenant, je suis vraiment confus.




Cela dépend de la machine virtuelle, mais System.arraycopy devrait vous donner le plus proche des performances natives.

J'ai travaillé pendant 2 ans en tant que développeur Java pour les systèmes embarqués (où la performance est une priorité énorme) et partout où System.arraycopy pourrait être utilisé, je l'ai surtout utilisé / vu utilisé dans le code existant. Il est toujours préféré sur les boucles lorsque la performance est un problème. Si la performance n'est pas un gros problème, j'irais avec la boucle, cependant. Beaucoup plus facile à lire.




System.arraycopy() est un appel natif qui copie l'opération directement dans la mémoire. La copie de la mémoire unique serait toujours plus rapide que votre boucle for




Comment est-il possible que Arrays.copyOf soit plus rapide que System.arraycopy s'il s'agit de l'implémentation de copyOf:

public static int[] copyOf(int[] original, int newLength) {
    int[] copy = new int[newLength];
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}



Related


Tags

java