【发布时间】:2021-10-19 14:28:11
【问题描述】:
我正在寻找一种用大量条目替换字符串的方法。
条目的大小可以是500~5000,其中大部分有不同的字符长度。条目中没有正则表达式。不会改变。
字符串的长度可以是 10~250。包含 Unicode,每一种都不同。
该方法每秒将被调用大约 100 次。每个都是异步的。
更换必须按顺序进行,并以最后更换为基础。
所以,我尝试过的方法是
public String method(String text) {
String result = text; // "This is a text. aabbuisaufdsafdsaa."
HashMap<String, String> map = getMap();
for (Map.Entry<String, String> entry : map.entrySet())
result = result.replace(entry.getKey(), entry.getValue());
return result;
}
非常慢。平均 31000 ns,包含 1000 个大小条目。
以及我目前使用的StringUtils的方法(commons-lang3 version 3.12.0):
private String[] searchList = null;
private String[] replacementList = null;
public String method(String text) {
String result = text; // "This is a text. aabbuisaufdsafdsaa."
result = StringUtils.replaceEachRepeatedly(result, getSearchList(), getReplacementList());
return result;
}
// Same with #getReplacementList.
private String[] getSearchList() {
// This will be init when this class loaded. I just paste it here.
if (this.searchList == null) {
HashMap<String, String> map = getMap();
this.searchList = new String[map.size()];
int index = 0;
for (Map.Entry<String, String> entry : map.entrySet()) {
this.searchList[index] = entry.getKey();
index++;
}
}
return this.searchList;
}
比上一个快 50%~70%。平均 11000 ns,包含 1000 个大小条目。
所以我正在寻找一种更好的方法,它可以更复杂。我唯一需要的是更快。
如果有任何想法,我将不胜感激!
【问题讨论】:
-
由于数据大且速度关键,没有通用的方法来解决它,您必须尽可能利用所有不变量(例如,频率
getMap()键/值更改?)考虑到一些不变量的差异可能是一个决定因素。此外,提供客观基准测试的实例。 -
感谢您的提问。运行过程中键/值不会改变。
-
你说没有正则表达式,但为什么不呢?它可能会加快速度。
-
那么 en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm 或 en.wikipedia.org/wiki/Commentz-Walter_algorithm 算法必须考虑在内,但输入数据的任何不变量也是有用的。
-
你是如何进行基准测试的? IDE 调试模式,HotSpot JVM 重新启动,还是代码运行多次后可以被 JIT 编译器优化?不妨看看原生模式下的 GraalVM。
标签: java string optimization