Java List/Mapのパフォーマンステストを実行しようとすると、奇妙なパフォーマンス結果が検出されます。値がハードコードされた文字列を使用すると、Javaマップのパフォーマンスが最悪になる
私のテストロジックは、データ準備とマップ操作を分割し、分離されたデータ準備プロセスは、マップ操作コストを正確に計算するオブジェクトです。
さまざまな文字列の作成方法が異なる結果の結果になることは理解できますが、奇妙なことは、特定のハードコードされた文字列を使用するとパフォーマンスが最悪になることです。
なぜこの結果はそうですか?ここで
は、テストコードで、パフォーマンスの結果は、私が正しいプロセスに従わなかったとして、それが悪いベンチマークですテストケースメソッドのコメント
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));
}
}
ベンチマークは間違っているため、得られる結果は完全に信頼できません。 https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – Kayaman
私は3番目(遅い)テストのランタイムはゴミを集めることによって支配されると確信しています第1および第2の試験から得た。テストはVALUESでのみ異なるので、KEYSではなくマップに格納するため、メインコードのパフォーマンスの違いはまったくありません。 Map.put()は値を調べません。短い文字列、長い文字列、中断されているかどうか、異なっていても同じであっても問題ありません。 –
これらの3つのテストケースは、互いに影響を及ぼさないはずです.3つのケースを同時に1つのプロセスで実行したり、1つのプロセスで1つのケースを実行したりしないでください。 3番目のケースは常に最悪のパフォーマンスになります。 –