This question already has an answer here:
这个问题在这里已有答案:
- java performance : Is storing a hashMap value in a variable redundant? 4 answers
- Is it better to store value as variable or call method again? 5 answers
- Calling getters on an object vs. storing it as a local variable (memory footprint, performance) 5 answers
- Java Method invocation vs using a variable 14 answers
java性能:将hashMap值存储在变量冗余中吗? 4个答案
将值存储为变量还是再次调用方法更好? 5个答案
在对象上调用getter与将其存储为局部变量(内存占用,性能)5个答案
Java方法调用与使用变量14的答案
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
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
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();
}