2009-11-16 4 views
1

Juste curieux, ce qui est plus efficace?Quel type de guillemet est plus efficace?

Ce:

String a = someString + "." + anotherString; 

Ou ceci:

String a = someString + '.' + anotherString; 
+4

Vous ne devriez vraiment pas vous en soucier, sauf si c'est tout ce que vous faites, des milliers de fois par seconde, pendant plusieurs heures. – Marius

+4

Aurait été bien si vous avez souligné que les citations étaient différentes. Passé une bonne minute avec ça. – mpen

+1

'' .'' est plus rapide. – jjnguy

Répondre

6

Ils sont assez similaires. '.' est légèrement plus rapide, mais la différence est négligeable (environ 20 ms dans une boucle de 10 millions).

Voici mon test:

$cat UsingC.java UsingS.java 
public class UsingC { 
    public static void main(String [] args) { 
     String someString = ""; 
     String anotherString = ""; 

     int i = 0; 
     while(i++ < 10000000) { 
      String a = someString + '.' + anotherString; 
     } 
    } 
} 
public class UsingS{ 
    public static void main(String [] args) { 
     String someString = ""; 
     String anotherString = ""; 

     int i = 0; 
     while(i++ < 10000000) { 
      String a = someString + "." + anotherString; 
     } 
    } 
} 
$for i in 1 2 3 4 5 ; do time java UsingC; done 

real 0m1.643s 
user 0m1.424s 
sys 0m0.108s 

real 0m1.670s 
user 0m1.468s 
sys 0m0.056s 

real 0m2.023s 
user 0m1.448s 
sys 0m0.080s 

real 0m1.669s 
user 0m1.432s 
sys 0m0.088s 

real 0m1.674s 
user 0m1.416s 
sys 0m0.104s 
$for i in 1 2 3 4 5 ; do time java UsingS; done 

real 0m2.344s 
user 0m1.584s 
sys 0m0.136s 

real 0m2.057s 
user 0m1.640s 
sys 0m0.084s 

real 0m2.112s 
user 0m1.732s 
sys 0m0.072s 

real 0m2.482s 
user 0m1.704s 
sys 0m0.108s 

real 0m2.134s 
user 0m1.788s 
sys 0m0.072s 

Vous pouvez faire une moyenne et/ou créer un test plus complexe.

Ils utilisent tous deux StringBuilder de manière interne.

+0

Le seul que actuall répond à la question – flybywire

+1

Sachez que les microbenchmarks peuvent être très délicats et décevants. Voir cet article par Brian Goetz, par exemple: http://www.ibm.com/developerworks/library/j-jtp12214/ – Jesper

+0

Il serait judicieux de vérifier au moins les codes d'octets Java générés pour s'assurer que la compilation n'a pas faire quelque chose d'intelligent. Alors tout ce dont vous avez à vous soucier est la JVM :-) –

13

Vous devriez vraiment pas de soins, à moins que cela est tout ce que vous faites, des milliers de fois par seconde, pendant plusieurs heures.

La rumeur veut que l'utilisation d'un StringBuilder soit la plus rapide. Essayez-les tous les deux, en boucle, un million de fois, et consignez le temps que cela prend, puis retournez nous au reste d'entre nous.

+2

Le compilateur remplacera ce code par un StringBuilder pour effectuer le travail. – Tom

+1

Toutefois, le compilateur ajoute * new StringBuilder() * juste avant l'ajout réel, ce qui le rend beaucoup plus lent en raison des allocations de mémoire objet/tableau lors d'une exécution répétée dans une boucle ou autre. – Esko

+0

J'ai suivi vos suggestions. Avec 1M, la différence n'était pas perceptible. J'ai essayé 10M, avec 10M la différence est juste un couple de ms. http://stackoverflow.com/questions/1740475/which-is-more-efficient/1740705#1740705 – OscarRyz

1

Le compilateur Java transformera toute expression de concaténation de chaîne en une séquence équivalente d'opérations StringBuilder. Il est prudent de supposer que la séquence sera proche de l'optimum. En effet, dans cet exemple particulier, je m'attendrais à ce que la même séquence (optimale) soit générée dans les deux cas. Mais même si ce n'est pas le cas, la différence risque d'être faible.

Cela ne vaut la peine de se soucier de ce genre de choses que si le profileur vous dit qu'une instruction particulière est un goulot d'étranglement dans votre code. L'optimisation prématurée est inutile (au mieux) et peut même être nuisible.

L'avis des Sun est que le code Java optimisé à la main peut être un code plus lent car la séquence de bytecode résultante devient trop complexe pour que le compilateur JIT puisse optimiser correctement. Le meilleur conseil est simplement d'écrire le code simplement et faire confiance aux compilateurs Javac et JIT pour faire du bon travail.

12

En regardant le code pour StringBuilder.append et AbstractStringBuilder.append, je voudrais attendre le '.' former pour être plus rapide.

Il a moins à faire, essentiellement:

  • Il n'a pas besoin de faire une vérification de nullité, que le charbon ne peut être nul
  • Il ne cherche pas à faire une optimisation pour un vide chaîne soit
  • il n'a pas besoin de chercher la longueur à ajouter - il sera toujours 1
  • il n'a qu'à effectuer une seule cession dans le tableau plutôt qu'une seule boucle itération

Comme tout le monde cependant, je ne m'attendrais pas à ce que la différence soit significative dans le vrai code d'application.

Je ne sais pas s'il serait valable pour le compilateur Java de réaliser que ce qui est en train d'être ajouté est une chaîne constante de longueur 1, et de la convertir en caractère littéral à la place - ou si cela dérangerait même si ce serait valide.

+0

Il est certainement valable pour le compilateur de le faire. Tout comme il est valide pour le compilateur de concaténer des chaînes littérales. –

+0

@Stephen: Aurait-il encore besoin d'interner le "." bien que? Est-ce que le fait que "." apparaît dans la source comme un littéral signifie qu'il doit être interné lorsque la classe est chargée? Peut-être pas - mais c'est le genre de choses dont ils devraient s'inquiéter, potentiellement. Cela semble une optimisation assez raisonnable. –

Questions connexes