哈希映射与数组性能

当数组的索引已知时,使用数组或哈希映射是否更好(性能方面)更好?请记住,示例中的“对象数组/映射”只是一个示例,在我的实际项目中,它是由另一个类生成的,因此我不能使用单个变量。

数组示例:

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看起来好多了,但我真的需要性能,以便具有优先级。

编辑:好吧,阵列就是这样,建议仍然欢迎

编辑:我忘了提一下,数组/哈希映射的大小总是一样的(6)

编辑:看起来哈希映射更快 数组:128ms 哈希: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();
}

}


答案 1

HashMap在下面使用数组,因此它永远不会比正确使用数组更快。

Random.nextInt()比您正在测试的内容慢很多倍,即使使用数组来测试数组也会使您的结果产生偏差。

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

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

微基准测试的一个常见问题是JIT,它非常擅长删除不执行任何操作的代码。如果你不小心,你只会测试你是否已经混淆了JIT,以至于它无法解决你的代码不做任何事情。

这是您可以编写微基准测试的原因之一,这些基准测试C++系统执行。这是因为Java是一种更简单的语言,更容易推理,因此可以检测出没有任何用处的代码。这可能导致测试表明Java“没有任何用处”的速度比C++ ;)


答案 2

知道索引时的数组速度更快(HashMap在幕后使用一个链表数组,这在数组访问上方增加了一些开销,更不用说需要完成的哈希操作了)

和FYI制作它,所以你不必投掷HashMap<String,SomeObject> objects = HashMap<String,SomeObject>();