Newsgroup: it.comp.java
Titolo: ("" + 1) o (String.valueOf(1))

Quando non si ha molto a cui pensare, sorgono sempre le domande più
assurde. :)
Consideriamo le seguenti istruzioni
 
	/*1*/ System.out.println("Ciao " + 1);
	/*2*/ System.out.println("Ciao " + String.valueOf(1));
	/*3*/ String s = "" + 1;
	/*4*/ String s1 = String.valueOf(1);
La domanda è: quale secondo voi è l'ottimizzazione (tempo/occupazione)
migliore.
I casi 1 e 2 sono, a mio avviso, grosso modo identici. Forse il caso 1
è un pelo più lento in compilazione perchè viene sostituito con
l'equivalente di 2 per poi essere messo in bytecode (o sarà
l'inverso?).
I casi 3 e 4 invece secondo me sono differenti. Sempre secondo me, il
caso 3, istanzia un oggetto di tipo stringa (vuota) e lo assegna ad
"s", per poi assegnare ad "s" un String.valueOf(1). Il caso 4 invece
risulterebbe ottimizzato in memoria ed esecuzione, in quanto
eviterebbe il passaggio di allocare un oggetto String in più, ma
assegnerebbe il valore "1" direttamente all'oggetto String "s1" appena
creato.
Aspetto vostri pareri riguardo questa mia s###a mentale :)
Ciao D.

 Ciao D.
Ciao
   Federico

 sullo stack.
In realta' il motivo e' che l'espressione ""+1 coinvolge solo costanti,
quindi puo' essere ottimizzata dal compilatore.
Infatti l'istruzione s=""+1 viene compilata (J2SDK 1.4.2_03) in:
ldc     #4; //String 1
astore_1
Quindi in esecuzione il tutto diventa la semplice assegnazione di una
costante stringa.
Mentre s=String.valueOf(1) diventa:
iconst_1
invokestatic    #13; //Method java/lang/String.valueOf:(I)Ljava/lang/String;
astore_1
Evitando di usare solo costanti, per poter fare un confronto piu' omogeneo
e con codice piu' verosimile, s=""+a diventa:
new     #4; //class StringBuffer
dup
invokespecial   #5; //Method java/lang/StringBuffer."<init>":()V
ldc     #6; //String
invokevirtual   #7; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
iload_3
invokevirtual   #8; //Method java/lang/StringBuffer.append:(I)Ljava/lang/StringBuffer;
invokevirtual   #9; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;
astore_1
Mentre s=String.valueOf(a) diventa:
iload_3
invokestatic    #14; //Method java/lang/String.valueOf:(I)Ljava/lang/String;
astore_1
Questa volta i tempi di esecuzione sono decisamente favorevoli alla
seconda soluzione:
tempo trascorso: 24166
tempo trascorso: 1678
rapp.: 0.06943639824546884
-- 
Lucio Benfante
Java User Group Padova: 
http://www.jugpadova.it
Brainbench MVP for Java 1: 
http://www.brainbench.com
MyTranscript: 
http://www.brainbench.com/transcript.jsp?pid=167064

 volte),
Le ho fatte anche 5 volte con WSAD e windows ed ecco i risultati
tempo trascorso ("" + 1): 170
tempo trascorso (String.valueOf(1)): 28802
rapp.: 169.42352941176472
tempo trascorso ("" + 1): 170
tempo trascorso (String.valueOf(1)): 28652
rapp.: 168.54117647058823
tempo trascorso ("" + 1): 170
tempo trascorso (String.valueOf(1)): 28731
rapp.: 169.00588235294117
tempo trascorso ("" + 1): 180
tempo trascorso (String.valueOf(1)): 28631
rapp.: 159.0611111111111
tempo trascorso ("" + 1): 171
tempo trascorso (String.valueOf(1)): 28621
rapp.: 167.37426900584796
su 5 tentativi, risulta ("" + 1) 166 volte piů veloce. Ho interpretato giusto? :)
Se mi ricordo, a casa provo su linux con eclipse e con jdk normale.
Ciao D.

 astore_1
Interessante!
Dove posso trovare le specifiche del byte code?
E come si ottengono questi listati?
Grazie
Federico

 E come si ottengono questi listati?
Devi usare il tool javap del J2SDK.


 Devi usare il tool javap del J2SDK.
Dimenticavo...la documentazione sul bytecode la trovi nella JVM
specification:
http://java.sun.com/docs/books/vmspec/index.html


 [...]
Grazie 1000!
Ciao
    Federico