私はString.equals()メソッドのより高速なバージョンを作成しようとしていて、それを単にコピーすることから始めました。私が見つけた結果は非常に紛らわしいものでした。コピーして貼り付けたバージョンを実行し、タイミングを合わせてJVMバージョンと比較すると、JVMバージョンの方が高速でした。差は6倍から34倍速くなりました!簡単に言えば、文字列が長いほど、違いは大きくなります。
boolean equals(final char a[], final char b[]) {
int n = a.length;
int i = 0;
while (n-- != 0) {
if (a[i] != b[i]) return false;
i++;
}
return true;
}
public static void main() throws Exception {
String a = "blah balh balh";
String b = "blah balh balb";
long me = 0, jvm = 0;
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
final char lhs[] = (char[]) value.get(a);
final char rhs[] = (char[]) value.get(b);
for (int i = 0; i < 100; i++) {
long t = System.nanoTime();
equals(lhs, rhs);
t = System.nanoTime() - t;
me += t;
}
for (int i = 0; i < 100; i++) {
long t = System.nanoTime();
a.equals(b);
t = System.nanoTime() - t;
jvm += t;
}
System.out.println("me = " + me);
System.out.println("jvm = " + jvm);
}
出力:
me = 258931
jvm = 14991
私が書いたequals()メソッドは、String.equals()メソッドにあるもののコピー貼り付けバージョンです。JVMバージョンがコピー貼り付けバージョンよりも速いのはなぜですか?事実上同じではないですか?
なぜ私がそのような目に見える違いを見るのか誰かが説明できますか?
PS:大きな違いを見たい場合は、最後に1文字だけ異なる長い(本当に本当に長い)文字列を作成できます。