文字列に英数字のみが含まれていることを確認する最も速い方法は何ですか。
多くの CPU を消費するコードがいくつかありますが、コンパイル済みの正規表現を使用するよりも高速な方法があるのではないかと考えています。
文字列に英数字のみが含まれていることを確認する最も速い方法は何ですか。
多くの CPU を消費するコードがいくつかありますが、コンパイル済みの正規表現を使用するよりも高速な方法があるのではないかと考えています。
次のようにString.matches()を使用します。
String myString = "qwerty123456";
System.out.println(myString.matches("[A-Za-z0-9]+"));
それは絶対的な「最速」の可能なアプローチではないかもしれません。しかし、一般に、言語の「標準ライブラリ」を書いている人々とパフォーマンスの点で競争しようとしても、あまり意味がありません。
正規表現を使用しない場合と比較して(他の回答に従って)正規表現を使用する場合のテストを作成しました。Java 1.6 を実行するクアッド コア OSX10.8 マシンで行われたテスト
興味深いことに、正規表現を使用すると、文字列を手動で反復処理するよりも約 5 ~ 10 倍遅くなります。さらに、このisAlphanumeric2()
関数は よりわずかに高速ですisAlphanumeric()
。1 つは拡張 Unicode 番号が許可されている場合をサポートし、もう 1 つは標準の ASCII 番号のみが許可されている場合をサポートします。
public class QuickTest extends TestCase {
private final int reps = 1000000;
public void testRegexp() {
for(int i = 0; i < reps; i++)
("ab4r3rgf"+i).matches("[a-zA-Z0-9]");
}
public void testIsAlphanumeric() {
for(int i = 0; i < reps; i++)
isAlphanumeric("ab4r3rgf"+i);
}
public void testIsAlphanumeric2() {
for(int i = 0; i < reps; i++)
isAlphanumeric2("ab4r3rgf"+i);
}
public boolean isAlphanumeric(String str) {
for (int i=0; i<str.length(); i++) {
char c = str.charAt(i);
if (!Character.isLetterOrDigit(c))
return false;
}
return true;
}
public boolean isAlphanumeric2(String str) {
for (int i=0; i<str.length(); i++) {
char c = str.charAt(i);
if (c < 0x30 || (c >= 0x3a && c <= 0x40) || (c > 0x5a && c <= 0x60) || c > 0x7a)
return false;
}
return true;
}
}
range: を指定するため、正規表現はおそらく非常に効率的です[0-9a-zA-Z]
。正規表現の実装コードが効率的であると仮定すると、これには各範囲の上限と下限の比較が必要になるだけです。基本的に、コンパイルされた正規表現が行うべきことは次のとおりです。
boolean isAlphanumeric(String str) {
for (int i=0; i<str.length(); i++) {
char c = str.charAt(i);
if (c < 0x30 || (c >= 0x3a && c <= 0x40) || (c > 0x5a && c <= 0x60) || c > 0x7a)
return false;
}
return true;
}
すべての文字をチェックする必要があり、比較はこれ以上簡単にはできないため、コードがこれよりも効率的であるとは思えません。