[英]Java Map got worst performance when value use hard-coded String
当我尝试对Java List / Map进行性能测试时,发现奇怪的性能结果。
我的测试逻辑分为数据准备和地图放置操作,分开的数据准备过程是正确计算地图操作成本的对象。
我可以理解不同的String创建方法会导致不同的性能结果,但是奇怪的是:使用一种特定的硬编码String会导致性能最差。
为什么这样的结果是这样。
这是测试代码,性能结果包含在测试用例方法注释中
package cn.codeworks.test;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Function;
import org.junit.Test;
public class TreeMapPerformanceTest {
private static final int dataSize = 1000 * 1000;
static class Pair {
private final Integer key;
private final String value;
public Pair(Integer key, String value) {
this.key = key;
this.value = value;
}
public Integer getKey() {
return key;
}
public String getValue() {
return value;
}
}
/**
* time cost (3 times) = 196, 178, 186
*/
@Test
public void testPutPerformance_string_intern() {
testPutPerformance((loc) -> new String("abc").intern());
}
/**
* time cost (3 times) = 275, 317, 331
*/
@Test
public void testPutPerformance_string_new() {
testPutPerformance((loc) -> new String("abc"));
}
/**
* this case got bad performance
* time cost (3 times) = 591, 565, 570
*/
@Test
public void testPutPerformance_string_hardcoded() {
testPutPerformance((loc) -> "abc");
}
private void testPutPerformance(Function<Integer, String> stringCreateMethod) {
// prepare data
List<Pair> data = new ArrayList(dataSize);
for (int i = 0; i < dataSize; i++) {
Pair pair = new Pair(i, stringCreateMethod.apply(i));
data.add(pair);
}
int size = data.size();
// map operation
Map<Integer, String> map = new TreeMap<>();
long startTimeMillis = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
Pair pair = data.get(i);
map.put(pair.getKey(), pair.getValue());
}
long endTimeMillis = System.currentTimeMillis();
System.out.println("time cost = " + (endTimeMillis - startTimeMillis));
}
}
由于我没有遵循正确的流程,因此这是一个糟糕的基准。
添加JVM选项-XX:+PrintCompilation -verbose:gc
,再次运行测试,这是3个测试用例的结果:
[Full GC (Ergonomics) 114779K->32543K(270848K), 0.2512151 secs]
[Full GC (Ergonomics) 141433K->35541K(340992K), 0.3268599 secs]
[Full GC (Ergonomics) 59544K->55008K(227328K), 0.9451788 secs]
对于每种情况,都发生了一次完全GC ,而最慢的情况花费了最长的GC时间。
并且在添加了JVM选项-Xms512m -Xmx512m
,期望避免在测试用例运行期间使用Full GC,这之间的时间成本差异消失了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.