簡體   English   中英

Hashmap 與數組性能

[英]Hashmap vs Array performance

當 Array 的索引已知時,使用 Arrays 或 HashMaps 是否(性能方面)更好? 請記住,示例中的“對象數組/映射”只是一個示例,在我的實際項目中,它是由另一個類生成的,因此我無法使用單個變量。

數組示例:

SomeObject[] objects = new SomeObject[2];
objects[0] = new SomeObject("Obj1");
objects[1] = new SomeObject("Obj2");

void doSomethingToObject(String Identifier){
    SomeObject object;
    if(Identifier.equals("Obj1")){
        object=objects[0];
    }else if(){
        object=objects[1];
    }
    //do stuff
}

哈希映射示例:

HashMap objects = HashMap();
objects.put("Obj1",new SomeObject());
objects.put("Obj2",new SomeObject());

void doSomethingToObject(String Identifier){
    SomeObject object = (SomeObject) objects.get(Identifier);
    //do stuff
}

HashMap 看起來好多了,但我真的需要在這方面的性能,以便優先考慮。

編輯:那么陣列就是這樣,仍然歡迎建議

編輯:我忘了提到,數組/HashMap 的大小總是相同的 (6)

編輯: HashMaps 似乎更快 Array: 128ms Hash: 103ms

當使用更少的周期時,HashMaps 的速度甚至是原來的兩倍

測試代碼:

import java.util.HashMap;
import java.util.Random;

public class Optimizationsest {
private static Random r = new Random();

private static HashMap<String,SomeObject> hm = new HashMap<String,SomeObject>();
private static SomeObject[] o = new SomeObject[6];

private static String[] Indentifiers = {"Obj1","Obj2","Obj3","Obj4","Obj5","Obj6"};

private static int t = 1000000;

public static void main(String[] args){
    CreateHash();
    CreateArray();
    long loopTime = ProcessArray();
    long hashTime = ProcessHash();
    System.out.println("Array: " + loopTime + "ms");
    System.out.println("Hash: " + hashTime + "ms");
}

public static void CreateHash(){
    for(int i=0; i <= 5; i++){
        hm.put("Obj"+(i+1), new SomeObject());
    }
}

public static void CreateArray(){
    for(int i=0; i <= 5; i++){
        o[i]=new SomeObject();
    }
}

public static long ProcessArray(){
    StopWatch sw = new StopWatch();
    sw.start();
    for(int i = 1;i<=t;i++){
        checkArray(Indentifiers[r.nextInt(6)]);
    }
    sw.stop();
    return sw.getElapsedTime();
}



private static void checkArray(String Identifier) {
    SomeObject object;
    if(Identifier.equals("Obj1")){
        object=o[0];
    }else if(Identifier.equals("Obj2")){
        object=o[1];
    }else if(Identifier.equals("Obj3")){
        object=o[2];
    }else if(Identifier.equals("Obj4")){
        object=o[3];
    }else if(Identifier.equals("Obj5")){
        object=o[4];
    }else if(Identifier.equals("Obj6")){
        object=o[5];
    }else{
        object = new SomeObject();
    }
    object.kill();
}

public static long ProcessHash(){
    StopWatch sw = new StopWatch();
    sw.start();
    for(int i = 1;i<=t;i++){
        checkHash(Indentifiers[r.nextInt(6)]);
    }
    sw.stop();
    return sw.getElapsedTime();
}

private static void checkHash(String Identifier) {
    SomeObject object = (SomeObject) hm.get(Identifier);
    object.kill();
}

}

HashMap 在底層使用數組,因此它永遠不會比正確使用數組更快。

Random.nextInt()比您正在測試的要慢很多倍,即使使用數組來測試數組也Random.nextInt()您的結果產生偏差。

您的數組基准測試如此緩慢的原因是由於相等比較,而不是數組訪問本身。

HashTable通常比HashMap慢得多,因為它做了很多相同的事情,但也是同步的。

微基准測試的一個常見問題是 JIT,它非常擅長刪除不做任何事情的代碼。 如果您不小心,您將只會測試您是否已經將 JIT 弄糊塗了,以至於它無法鍛煉您的代碼並沒有做任何事情。

這是您可以編寫超越 C++ 系統的微基准測試的原因之一。 這是因為 Java 是一種更簡單的語言,更容易推理並因此檢測沒有任何用處的代碼。 這可能導致測試表明 Java“沒有任何用處”比 C++ 快得多;)

知道索引時的數組更快(HashMap 在幕后使用了一個鏈表數組,這在數組訪問之上增加了一點開銷,更不用說需要完成的散列操作)

和僅供參考HashMap<String,SomeObject> objects = HashMap<String,SomeObject>(); 使它這樣你就不必施法

對於顯示的示例,我相信 HashTable 獲勝。 數組方法的問題在於它不能擴展。 我想你想要在表中有兩個以上的條目,並且 doSomethingToObject 中的條件分支樹會很快變得笨拙和緩慢。

從邏輯上講, HashMap絕對適合您的情況。 從性能的角度來看也是勝利,因為在數組的情況下,您需要進行多次字符串比較(在您的算法中),而在 HashMap 中,如果負載因子不太高,您只需使用哈希碼。 如果添加許多元素,則數組和 HashMap 都需要調整大小,但在 HashMap 的情況下,您還需要重新分配元素。 在這個用例中 HashMap 失敗了。

請永遠不要使用擴展if / else如果/ else if / else if / else if / else if / else if like else。 我重復這么多次的原因只是讓你覺得你的java解釋器在碰到像這樣的代碼塊時會這樣做。

如果你有多個其他的,請使用hashmap或switch / case(java 7將允許你在Strings上執行,而java 6則必須使用枚舉)。 用於只讀檢查的更好的解決方案是來自像番石榴這樣的框架的ImmutableMap; 它們具有高度優化的讀取,因為它們不允許寫入。

數組通常比集合類更快。

附注。 您在帖子中提到了 HashTable。 HashTable 的性能甚至比 HashMap 還要差。 我認為你提到的 HashTable 是一個錯字

“HashTable 看起來好多了”

這個例子很奇怪。 關鍵問題是您的數據是否是動態的。 如果是這樣,您就不能以這種方式編寫程序(如在數組情況下)。 換句話說,您的數組和哈希實現之間的比較是不公平的。 散列實現適用於動態數據,但數組實現不適用。

如果您只有靜態數據(6 個固定對象),則數組或散列僅用作數據持有者。 您甚至可以定義靜態對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM