En Java, si je joue plusieurs méthodes sur un objet, je peux les enchaîner, ou je peux faire une variable temporaire, comme siEst-ce que les méthodes de chaînage et la création de variables temporaires en Java affectent l'allocation de mémoire?
Chaînage
System.out.println(str.substring(0,4).substring(0,2));
variable Temp
String tmp = str.substring(0,4);
tmp = tmp.substring(0,2);
System.out.println(tmp);
De toute évidence, la différence est négligeable dans cet exemple, mais pourrait avoir un impact lorsque vous le faites sur des milliers de chaînes/un autre objet. Ma question est, est-ce que l'un d'entre eux est plus «efficace» en termes de ne pas faire des allocations d'objets supplémentaires ou de remplir le tas (et donc de faire appel au GC plus tôt)?
J'ai essayé de comparer les bytecodes des deux dans une boucle sur quelques chaînes, mais il semble similaire, sans pour les dernières lignes. Je ne comprends pas tous les appels bytecode, donc je ne suis pas sûr si l'un de ces derniers a à voir avec l'allocation de nouveaux objets.
Compiled from "TestNoTmp.java"
public class TestNoTmp {
public TestNoTmp();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_4
1: anewarray #2 // class java/lang/String
4: dup
5: iconst_0
6: ldc #3 // String These
8: aastore
9: dup
10: iconst_1
11: ldc #4 // String Are__
13: aastore
14: dup
15: iconst_2
16: ldc #5 // String Some_
18: aastore
19: dup
20: iconst_3
21: ldc #6 // String Strings
23: aastore
24: astore_1
25: aload_1
26: astore_2
27: aload_2
28: arraylength
29: istore_3
30: iconst_0
31: istore 4
33: iload 4
35: iload_3
36: if_icmpge 69
39: aload_2
40: iload 4
42: aaload
43: astore 5
45: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
48: aload 5
50: iconst_0
51: iconst_4
52: invokevirtual #8 // Method java/lang/String.substring:(II)Ljava/lang/String;
55: iconst_0
56: iconst_2
57: invokevirtual #8 // Method java/lang/String.substring:(II)Ljava/lang/String;
60: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
63: iinc 4, 1
66: goto 33
69: return
}
public class TestTmp {
public TestTmp();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_4
1: anewarray #2 // class java/lang/String
4: dup
5: iconst_0
6: ldc #3 // String These
8: aastore
9: dup
10: iconst_1
11: ldc #4 // String Are__
13: aastore
14: dup
15: iconst_2
16: ldc #5 // String Some_
18: aastore
19: dup
20: iconst_3
21: ldc #6 // String Strings
23: aastore
24: astore_1
25: aload_1
26: astore_2
27: aload_2
28: arraylength
29: istore_3
30: iconst_0
31: istore 4
33: iload 4
35: iload_3
36: if_icmpge 77
39: aload_2
40: iload 4
42: aaload
43: astore 5
45: aload 5
47: iconst_0
48: iconst_4
49: invokevirtual #7 // Method java/lang/String.substring:(II)Ljava/lang/String;
52: astore 6
54: aload 6
56: iconst_0
57: iconst_2
58: invokevirtual #7 // Method java/lang/String.substring:(II)Ljava/lang/String;
61: astore 6
63: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
66: aload 6
68: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
71: iinc 4, 1
74: goto 33
77: return
}
Eh bien, voici votre réponse. Alors que 'javac' ne fait pas beaucoup d'optimisation, ce genre de choses mineures n'a aucun effet sur le bytecode résultant. En outre, vous pouvez vous concentrer sur les goulots d'étranglement des performances réelles. Ce ne serait pas un, même si la variable temp affectait le bytecode. – Kayaman
Le bytecode varie légèrement, donc je n'étais pas sûr si cela a eu un impact, ou si mon hypothèse était bonne (j'aurais pu écrire mon exemple d'une manière qui ne fait pas de différence) – Parker
Ça ne fait pas de différence . –