1: HashMap<String, String> test = new HashMap<>();
2: Map<String, String> test = new HashMap<>();
只进行put、get操作
请问1的性能会优于2吗?为什么?
伊谢尔伦2017-04-17 14:47:38
HashMap map1 = 新しい HashMap<>();
マップ<文字列, 文字列> map2 = 新しい HashMap<>();
map1.put("a", "b");
map2.put("a", "b");
=>
16 aload_1 [map1]
17 ldc <文字列 "a"> [160]
19 ldc <文字列 "b"> [162]
21 invokevirtual java.util.HashMap.put(java.lang.Object, java.lang.Object) : java.lang.Object [164]
24ポップ
25 aload_2 [マップ2]
26 ldc <文字列 "a"> [160]
28 ldc <文字列 "b"> [162]
30 invokeinterface java.util.Map.put(java.lang.Object, java.lang.Object) : java.lang.Object [168] [nargs: 3]
ここの調査中、http://bobah.net/book/export/html/55
invokeinterface 可能性低い 38%
http://stackoverflow.com/questions/1504633/what-is-the-point-of-invokeinterface
ここ有解释
阿神2017-04-17 14:47:38
この質問に対する一般的な答えは、「ほぼ同じで、違いはありません」です。
より極端な答えは、「2 のパフォーマンスは 1 よりわずかに優れています」です。
次のコード:
HashMap<String, String> m1 = new HashMap<>();
m1.put("テスト", "テスト");
m1.get("テスト");
Map<String, String> m2 = new HashMap<>();
m2.put("テスト", "テスト");
m2.get("テスト");
バイトコードにコンパイルした後の対応する命令は次のとおりです。
0: new #16 // クラス java/util/HashMap
3: ダップ
4: invokespecial #18 // メソッド java/util/HashMap."":()V
7:astore_1
8: ロード_1
9: ldc #19 // 文字列テスト
11: ldc #19 // 文字列テスト
13: invokevirtual #21 // メソッド java/util/HashMap.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
16:ポップ
17: aload_1
18: ldc #19 // 文字列テスト
20: invokevirtual #25 // メソッド java/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;
23:ポップ
24: 新しい #16 // クラス java/util/HashMap
27:ダップ
28: invokespecial #18 // メソッド java/util/HashMap."":()V
31: アストア_2
32: ロード_2
33: ldc #19 // 文字列テスト
35: ldc #19 // 文字列テスト
37: invokeinterface #29, 3 // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
42:ポップ
43: ロード_2
44: ldc #19 // 文字列テスト
46: invokeinterface #32, 2 // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
51:ポップ
52: リターン
ケース 1 のマップの put/get 操作は invokevirtual
命令を使用して完了し、ケース 2 のマップの put/get 操作は < を使用して完了することがわかります。 code>invokeinterface コマンドが完了しました。
実装に関しては、invokevirtual
のパフォーマンスが invokeinterface
よりわずかに優れているため、どちらのパフォーマンスが優れているかと言えば、2 です。 p>
最後に、注意事項として、Java プログラミングのプロセスでは、すべての jvm 命令は、それが invokedynamic
であっても、ほぼ同じ一定レベルの時間オーバーヘッドがあると見なされるべきです。上位レベルのアルゴリズムを提供し、ロジックの最適化は統合された干渉のない視点をもたらします。
JVM 命令をエッジの効いた方法で選択するために Java コードの記述方法を変更するのは非合理であり、その結論も不安定です- jvm がアップグレードされると変更される可能性があります。さらに、この「パフォーマンスの向上」によってもたらされるコードの変更は可読性と保守性の低下につながり、利益に値しません