Hashmap与arrays性能

当Array的索引已知时,使用Arrays或HashMaps更好(性能方面)吗? 请记住,示例中的’objects array / map’只是一个示例,在我的实际项目中它由另一个类生成,所以我不能使用单个变量。

ArrayExample:

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 } 

HashMapExample:

 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看起来要好得多,但我真的需要这方面的表现才能优先考虑。

编辑:井阵,那么,建议仍然欢迎

编辑:我忘了提一下,Array / HashMap的大小总是一样的(6)

编辑:似乎HashMaps更快的数组:128毫秒哈希:103毫秒

当使用较少的周期时,HashMaps甚至快了两倍

测试代码:

 import java.util.HashMap; import java.util.Random; public class Optimizationsest { private static Random r = new Random(); private static HashMap hm = new HashMap(); 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()比你测试的慢很多倍,即使使用数组来测试数组也会偏向你的结果。

您的arrays基准测试速度如此之慢的原因是由于等于比较,而不是arrays访问本身。

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

微基准测试的一个常见问题是JIT非常擅长删除无法执行任何操作的代码。 如果你不小心,你只会测试你是否已经混淆了JIT,它无法锻炼你的代码什么都不做。

这是您可以编写执行C ++系统的微基准测试的原因之一。 这是因为Java是一种更简单的语言,更易于推理,从而检测出无用的代码。 这可以导致测试表明Java“没有用”比C ++快得多;)

知道索引的数组更快(HashMap在幕后使用链接列表数组,这会在数组访问之上增加一些开销,更不用说需要完成的散列操作)

和FYI HashMap objects = HashMap(); 这样你就不必投了

对于显示的示例,HashTable赢了,我相信。 arrays方法的问题在于它不能扩展。 我想你想在表中有两个以上的条目,并且doSomethingToObject中的条件分支树将很快变得笨拙和缓慢。

从逻辑上讲, HashMap绝对适合您的情况。 从性能角度来看也是胜利,因为在数组的情况下,你需要进行多次字符串比较(在算法中),而在HashMap中,如果加载因子不是太高,你只需要使用哈希码。 如果添加许多元素,则需要调整数组和HashMap的大小,但是在HashMap的情况下,您还需要重新分配元素。 在这个用例中,HashMap失败了。

数组通常比Collections类快。

PS。 你在post中提到了HashTable。 HashTable的性能甚至比HashMap还差。 我假设你提到HashTable是一个错字

“HashTable看起来好多了”

这个例子很奇怪。 关键问题是您的数据是否是动态的。 如果是,你不能用这种方式编写程序(如在数组的情况下)。 换句话说,比较你的数组和哈希实现是不公平的。 哈希实现适用于动态数据,但数组实现不适用。

如果您只有静态数据(6个固定对象),则数组或散列仅用作数据持有者。 你甚至可以定义静态对象。

请永远不要使用扩展if / else if / else if / else if / else if / else if / else if if else。 我重复这么多次的原因只是为了让你觉得你的java解释器在碰到像这样的代码块时会这样做。

如果你有多个其他的,无论是使用hashmap还是switch / case(java 7会让你在Strings上执行,而java 6则必须使用enum)。 用于只读检查的更好的解决方案是来自像番石榴这样的框架的ImmutableMap; 它们具有高度优化的读取,因为它们不允许写入。