问一个JAVA代码性能问题
迷茫
迷茫 2017-04-17 14:45:38
0
3
849

1: HashMap<String, String> test = new HashMap<>();
2: Map<String, String> test = new HashMap<>();

只进行put、get操作
请问1的性能会优于2吗?为什么?

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全員に返信(3)
伊谢尔伦
 HashMap map1 = 新しい HashMap<>();
    マップ map2 = 新しい HashMap<>();
    map1.put("a", "b");
    map2.put("a", "b");
    

=>

16 aload_1 [map1]
17 ldc  [160]
19 ldc  [162]
21 invokevirtual java.util.HashMap.put(java.lang.Object, java.lang.Object) : java.lang.Object [164]
24ポップ
25 aload_2 [マップ2]
26 ldc  [160]
28 ldc  [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
ここ有解释

いいねを押す +0
阿神

この質問に対する一般的な答えは、「ほぼ同じで、違いはありません」です。
より極端な答えは、「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 操作は invokeinterface コマンドが完了しました。

実装に関しては、invokevirtual のパフォーマンスが invokeinterface よりわずかに優れているため、どちらのパフォーマンスが優れているかと言えば、2 です。 p>

最後に、注意事項として、Java プログラミングのプロセスでは、すべての jvm 命令は、それが invokedynamic であっても、ほぼ同じ一定レベルの時間オーバーヘッドがあると見なされるべきです。上位レベルのアルゴリズムを提供し、ロジックの最適化は統合された干渉のない視点をもたらします。
JVM 命令をエッジの効いた方法で選択するために Java コードの記述方法を変更するのは非合理であり、その結論も不安定です- jvm がアップグレードされると変更される可能性があります。さらに、この「パフォーマンスの向上」によってもたらされるコードの変更は可読性と保守性の低下につながり、利益に値しません

いいねを押す +0
左手右手慢动作

運用方法によれば、2 のパフォーマンスは 1 よりも優れています。

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート