char[]
想象一下,您想计算给定包含多少个非 ASCII 字符。想象一下,性能真的很重要,所以我们可以跳过我们最喜欢的口号。
最简单的方法显然是
int simpleCount() {
int result = 0;
for (int i = 0; i < string.length; i++) {
result += string[i] >= 128 ? 1 : 0;
}
return result;
}
然后你会认为许多输入都是纯 ASCII 的,单独处理它们可能是个好主意。为简单起见,假设您只写了这个
private int skip(int i) {
for (; i < string.length; i++) {
if (string[i] >= 128) break;
}
return i;
}
这种微不足道的方法可能对更复杂的处理有用,在这里它不会造成任何伤害,对吧?所以让我们继续
int smartCount() {
int result = 0;
for (int i = skip(0); i < string.length; i++) {
result += string[i] >= 128 ? 1 : 0;
}
return result;
}
它与 相同simpleCount
。我称其为“智能”,因为要完成的实际工作更加复杂,因此快速跳过 ASCII 是有意义的。如果没有或非常短的 ASCII 前缀,它可能会花费更多的周期,但仅此而已,对吗?
也许你想这样重写它,它是一样的,只是可能更可重用,对吧?
int smarterCount() {
return finish(skip(0));
}
int finish(int i) {
int result = 0;
for (; i < string.length; i++) {
result += string[i] >= 128 ? 1 : 0;
}
return result;
}
然后你在一些非常长的随机字符串 上运行基准测试并得到这个 参数确定 ASCII 与非 ASCII 的比率以及非 ASCII 序列的平均长度,但正如你所见,它们并不重要。尝试不同的种子,什么都无所谓。基准使用caliper ,因此通常的陷阱不适用。结果相当可重复,末尾的小黑条表示最小和最大时间。
有人知道这里发生了什么吗?任何人都可以复制它吗?