我正在处理一个交易处理应用程序,我必须处理很多字符串。其中一些字符串是非重复的,例如商品ID,而其他字符串经常重复,例如产品ID。
我正在考虑将所有交易属性作为通用步骤进行分析,同时解析交易消息(JSON)以减少内存使用并加快相等性检查。
我的问题是,我是否可能会因此移动无意中降低性能?
答案 0 :(得分:3)
重复编写常用字符串通常是节省内存的好主意
但绝不要将String.intern
用于重复数据删除!
String.intern
是一种原生方法;每次通话都会遇到额外的JNI overhead。常规HashMap
或ConcurrentHashMap
可以更好地完成此任务。
以下基准测试比较了1M字符串集上String.intern
与[Concurrent]HashMap.putIfAbsent
的效果:
@State(Scope.Benchmark)
public class Dedup {
private static final HashMap<String, String> HM = new HashMap<>();
private static final ConcurrentHashMap<String, String> CHM = new ConcurrentHashMap<>();
private static final int SIZE = 1024 * 1024;
private static final String[] STRINGS = new Random(0).ints(SIZE)
.mapToObj(Integer::toString)
.toArray(String[]::new);
int idx;
@Benchmark
public String intern() {
String s = nextString();
return s.intern();
}
@Benchmark
public String hashMap() {
String s = nextString();
String prev = HM.putIfAbsent(s, s);
return prev != null ? prev : s;
}
@Benchmark
public String concurrentHashMap() {
String s = nextString();
String prev = CHM.putIfAbsent(s, s);
return prev != null ? prev : s;
}
private String nextString() {
return STRINGS[++idx & (SIZE - 1)];
}
}
JDK 9的结果(越小越好):
Benchmark Mode Cnt Score Error Units
Dedup.concurrentHashMap avgt 10 91,208 ± 0,569 ns/op
Dedup.hashMap avgt 10 73,917 ± 0,602 ns/op
Dedup.intern avgt 10 832,700 ± 73,402 ns/op