将值存储在变量中还是调用HashMap函数? [重复]

时间:2021-02-09 15:41:33

This question already has an answer here:

这个问题在这里已有答案:

When you need to call a HashMap's get on the same value a few times within a for loop, would it be more efficient to store it in a variable or to make the call two or three times?

当你需要在for循环中调用HashMap获取相同的值几次时,将它存储在变量中还是调用两次或三次更有效?

5 个解决方案

#1


1  

Retrieving a value from a HashMap is an O(1) operation, assuming your keys have a reasonable implementation of hashCode().

从HashMap中检索值是一个O(1)操作,假设您的键具有hashCode()的合理实现。

If you're only retrieving this object a couple of times it may be a micro-optimization (read: premature optimization) to store it in a local variable, but you probably won't notice any difference either way. The real reason to store such an object in a local variable is to avoid duplicating boiler-plate code that checks the key really exists in the map, the value isn't null, etc.

如果您只是多次检索此对象,则可能需要进行微优化(读取:过早优化)以将其存储在局部变量中,但您可能不会注意到任何差异。将这样的对象存储在局部变量中的真正原因是为了避免重复检查地图中确实存在的密钥的样板代码,该值不为空等。

#2


1  

Accessing data in HashMap is O(1), so in general it's quite fast. However, if you initiate a variable with the proper value from the HashMap it would be a little bit faster. If you are accessing HashMap with some key, firstly hashCode method of the key is called. If you call that once - it would be faster.

在HashMap中访问数据是O(1),因此通常它非常快。但是,如果从HashMap启动具有适当值的变量,则速度会快一些。如果您使用某个键访问HashMap,则首先调用该键的hashCode方法。如果你打电话一次 - 它会更快。

My experience shows that preparing a variable for such cases is a better solution not only because of performance purposes but also because of refactoring. If it happened you had to change some code, you made one change in HashMap call instead of many in different lines, leaving often one line unchanged (which leads to a bug).

我的经验表明,为这种情况准备一个变量是一个更好的解决方案,不仅是因为性能目的,还因为重构。如果它发生了你必须改变一些代码,你在HashMap调用中进行了一次更改,而不是在不同的行中进行了多次更改,通常会使一行保持不变(这会导致错误)。

#3


0  

HashMap get runs in constant time. So from efficiency point of view, it doesn't matter. Although storing the value in a variable is more cleaner.

HashMap以恒定的时间运行。所以从效率的角度来看,没关系。虽然将值存储在变量中更加清晰。

#4


0  

Calling hashmap.get() creates an indirection, therefor it's will be slower than a direct variable reference. The fact that hashmap.get() has O(1) complexity has absolutely nothing to do with the answer to this question, because O(1) complexity only means that the execution complexity of the algorithm does not increase with a growing number of elements, but, it does not say anything about how many cpu cycles a run takes, it only states that it's constant. Storing the result in a variable would probably be the most performant.

调用hashmap.get()会创建一个间接,因此它会比直接变量引用慢。 hashmap.get()具有O(1)复杂度的事实与此问题的答案完全无关,因为O(1)复杂性仅意味着算法的执行复杂性不会随着元素数量的增加而增加但是,它没有说明运行需要多少cpu周期,它只表明它是恒定的。将结果存储在变量中可能是最高效的。

#5


-1  

I've made a simple test with HashMap<String, String>, where both keys and values are random-generated 64-character strings. It uses 1.000.000 records in the map and goes through each of them in 2 for-loops: First is calling get() once and saving it to variable. Second is calling get() 3 times. This is done in 5 iterations.

我用HashMap 进行了一个简单的测试,其中键和值都是随机生成的64个字符的字符串。它在地图中使用了1.000.000个记录,并在2个for循环中遍历每个记录:首先调用get()一次并将其保存到变量。第二个是调用get()3次。这是在5次迭代中完成的。 ,string>

Results (in milliseconds):

结果(以毫秒为单位):

                      1    2    3    4    5      avg
Store in a variable: 125  126  103  104  102  |  112
Call 3 times:        151  135  137  134  152  |  142

So, for this configuration (map of string-string), calling get() once and storing result in a variable is more effective.

因此,对于此配置(字符串字符串的映射),调用get()一次并将结果存储在变量中更有效。


Code of the test:

测试代码:

ArrayList<String> keys;
HashMap<String, String> data;

void run() {
    generateData(1_000_000);

    long start, end;

    for (int i = 0; i < 5; ++i) {
        start = System.nanoTime();
        for (String key : keys) {
            String value = data.get(key);
        }
        end = System.nanoTime();
        System.out.println("Store in a variable: " + ((end - start) / 1000 / 1000) + "ms");

        start = System.nanoTime();
        for (String key : keys) {
            data.get(key);
            data.get(key);
            data.get(key);
        }
        end = System.nanoTime();
        System.out.println("Call 3 times: " + ((end - start) / 1000 / 1000) + "ms");
    }
}

void generateData(int size) {
    keys = new ArrayList<>(size);
    data = new HashMap<>(size);
    for (int i = 0; i < size; ++i) {
        String key = getRandomString(64);
        keys.add(key);
        data.put(key, getRandomString(64));
    }
}

String getRandomString(int length) {
    StringBuilder str = new StringBuilder();
    for (int i = 0; i < length; ++i) {
        str.append((char) ThreadLocalRandom.current().nextInt(128));
    }
    return str.toString();
}

#1


1  

Retrieving a value from a HashMap is an O(1) operation, assuming your keys have a reasonable implementation of hashCode().

从HashMap中检索值是一个O(1)操作,假设您的键具有hashCode()的合理实现。

If you're only retrieving this object a couple of times it may be a micro-optimization (read: premature optimization) to store it in a local variable, but you probably won't notice any difference either way. The real reason to store such an object in a local variable is to avoid duplicating boiler-plate code that checks the key really exists in the map, the value isn't null, etc.

如果您只是多次检索此对象,则可能需要进行微优化(读取:过早优化)以将其存储在局部变量中,但您可能不会注意到任何差异。将这样的对象存储在局部变量中的真正原因是为了避免重复检查地图中确实存在的密钥的样板代码,该值不为空等。

#2


1  

Accessing data in HashMap is O(1), so in general it's quite fast. However, if you initiate a variable with the proper value from the HashMap it would be a little bit faster. If you are accessing HashMap with some key, firstly hashCode method of the key is called. If you call that once - it would be faster.

在HashMap中访问数据是O(1),因此通常它非常快。但是,如果从HashMap启动具有适当值的变量,则速度会快一些。如果您使用某个键访问HashMap,则首先调用该键的hashCode方法。如果你打电话一次 - 它会更快。

My experience shows that preparing a variable for such cases is a better solution not only because of performance purposes but also because of refactoring. If it happened you had to change some code, you made one change in HashMap call instead of many in different lines, leaving often one line unchanged (which leads to a bug).

我的经验表明,为这种情况准备一个变量是一个更好的解决方案,不仅是因为性能目的,还因为重构。如果它发生了你必须改变一些代码,你在HashMap调用中进行了一次更改,而不是在不同的行中进行了多次更改,通常会使一行保持不变(这会导致错误)。

#3


0  

HashMap get runs in constant time. So from efficiency point of view, it doesn't matter. Although storing the value in a variable is more cleaner.

HashMap以恒定的时间运行。所以从效率的角度来看,没关系。虽然将值存储在变量中更加清晰。

#4


0  

Calling hashmap.get() creates an indirection, therefor it's will be slower than a direct variable reference. The fact that hashmap.get() has O(1) complexity has absolutely nothing to do with the answer to this question, because O(1) complexity only means that the execution complexity of the algorithm does not increase with a growing number of elements, but, it does not say anything about how many cpu cycles a run takes, it only states that it's constant. Storing the result in a variable would probably be the most performant.

调用hashmap.get()会创建一个间接,因此它会比直接变量引用慢。 hashmap.get()具有O(1)复杂度的事实与此问题的答案完全无关,因为O(1)复杂性仅意味着算法的执行复杂性不会随着元素数量的增加而增加但是,它没有说明运行需要多少cpu周期,它只表明它是恒定的。将结果存储在变量中可能是最高效的。

#5


-1  

I've made a simple test with HashMap<String, String>, where both keys and values are random-generated 64-character strings. It uses 1.000.000 records in the map and goes through each of them in 2 for-loops: First is calling get() once and saving it to variable. Second is calling get() 3 times. This is done in 5 iterations.

我用HashMap 进行了一个简单的测试,其中键和值都是随机生成的64个字符的字符串。它在地图中使用了1.000.000个记录,并在2个for循环中遍历每个记录:首先调用get()一次并将其保存到变量。第二个是调用get()3次。这是在5次迭代中完成的。 ,string>

Results (in milliseconds):

结果(以毫秒为单位):

                      1    2    3    4    5      avg
Store in a variable: 125  126  103  104  102  |  112
Call 3 times:        151  135  137  134  152  |  142

So, for this configuration (map of string-string), calling get() once and storing result in a variable is more effective.

因此,对于此配置(字符串字符串的映射),调用get()一次并将结果存储在变量中更有效。


Code of the test:

测试代码:

ArrayList<String> keys;
HashMap<String, String> data;

void run() {
    generateData(1_000_000);

    long start, end;

    for (int i = 0; i < 5; ++i) {
        start = System.nanoTime();
        for (String key : keys) {
            String value = data.get(key);
        }
        end = System.nanoTime();
        System.out.println("Store in a variable: " + ((end - start) / 1000 / 1000) + "ms");

        start = System.nanoTime();
        for (String key : keys) {
            data.get(key);
            data.get(key);
            data.get(key);
        }
        end = System.nanoTime();
        System.out.println("Call 3 times: " + ((end - start) / 1000 / 1000) + "ms");
    }
}

void generateData(int size) {
    keys = new ArrayList<>(size);
    data = new HashMap<>(size);
    for (int i = 0; i < size; ++i) {
        String key = getRandomString(64);
        keys.add(key);
        data.put(key, getRandomString(64));
    }
}

String getRandomString(int length) {
    StringBuilder str = new StringBuilder();
    for (int i = 0; i < length; ++i) {
        str.append((char) ThreadLocalRandom.current().nextInt(128));
    }
    return str.toString();
}