[英]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.