2024年6月21日
问题
今天突然有个代码步骤变快了,之前要几分钟执行完成,突然十几秒就能结束,这两天只调整了用replaceAll替换字符串的地方,写了一段程序一测,还真是! 旧逻辑:近万条数据,每条可能要替换几百个字符,很耗时,每条都当做O(N) 新逻辑:每条先检查长度,要替换的字符超过6个直接换成"******",快,每条当做O(1) 艹昨天我还写正则预查哪哪好用,今天就打脸
测试代码
写代码测了下两种耗时,一万条String,每条替换中间的100个字符
java
public class Main {
public static void main(String[] args) {
int size = 10000;//一万
// 104个字符
String s = "xx1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890xx";
List<String> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(s);
}
{
long begin = System.currentTimeMillis();
List<String> res = new ArrayList<>(size);
list.forEach(item -> {
String str = item.replaceAll("(?<=.{2}).(?=.{2})", "*");
res.add(str);
});
long end = System.currentTimeMillis();
System.out.println("正则替换:(?<=.{2}).(?=.{2}) 替换每个字符,耗时毫秒:" + (end - begin));
}
{
long begin = System.currentTimeMillis();
List<String> res = new ArrayList<>(size);
list.forEach(item -> {
String str = item.substring(0,4) + "******";
res.add(str);
});
long end = System.currentTimeMillis();
System.out.println("普通替换字符,耗时毫秒:" + (end - begin));
}
}
}
结果,正则替换250ms,截取替换只要3ms
java
正则替换:(?<=.{2}).(?=.{2}) 替换每个字符,耗时毫秒:250
普通替换字符,耗时毫秒:3
时间差距不大,换成一百万条数据再试,一百万条数据每条替换100个字符,好,时间差了300倍:
java
正则替换:(?<=.{2}).(?=.{2}) 替换每个字符,耗时毫秒:8221
普通替换字符,耗时毫秒:27
又试了下一万条条数据每条替换100*100个字符,正则替换数量级相近,普通替换只要2ms
java
正则替换:(?<=.{2}).(?=.{2}) 替换每个字符,耗时毫秒:7292
普通替换字符,耗时毫秒:2
结论,replaceAll用正则逐个替换字符效率不太乐观,一万×一万个字符耗时7-8秒;普通替换字符串方法受数据量影响,但不是很大,都比较快