文字列からいくつかの数値を効率的に抽出しようとして、試してみました
- java.util.regex.Matcher
- com.google.common.base.Splitter
結果は次のとおりです。
- 正規表現経由: 24417 ミリ秒
- Google スプリッター経由: 17730 ミリ秒
あなたが推奨できる別のより速い方法はありますか?
Javaで文字列から複数の整数を抽出する方法など、以前に同様の質問があったことを知っていますか? しかし、私の重点は、これが頻繁に発生するため、これを高速に (ただし保守可能/シンプルに) することです。
編集:以下のアンドレア・リギオスの結果と結びつく私の最終結果は次のとおりです。
- 正規表現 (括弧なし) : 18857
- Google スプリッター (不要な trimResults() メソッドなし): 15329
- 以下の Martijn Courteaux の回答: 4073
import org.junit.Test;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Sample {
final static int COUNT = 50000000;
public static final String INPUT = "FOO-1-9-BAR1"; // I want 1, 9, 1
@Test
public void extractNumbers() {
long startTime = System.currentTimeMillis();
for (int i = 0; i < COUNT; i++) {
// Output is list of 1, 9, 1
Demo.extractNumbersViaGoogleSplitter(INPUT);
}
System.out.println("Total execution time (ms) via Google Splitter: " + (System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < COUNT; i++) {
// Output is list of 1, 9, 1
Demo.extractNumbersViaRegEx(INPUT);
}
System.out.println("Total execution time (ms) Regular Expression: " + (System.currentTimeMillis() - startTime));
}
}
class Demo {
static List<Integer> extractNumbersViaGoogleSplitter(final String text) {
Iterator<String> iter = Splitter.on(CharMatcher.JAVA_DIGIT.negate()).trimResults().omitEmptyStrings().split(text).iterator();
final List<Integer> result = new ArrayList<Integer>();
while (iter.hasNext()) {
result.add(Integer.parseInt(iter.next()));
}
return result;
}
/**
* Matches all the numbers in a string, as individual groups. e.g.
* FOO-1-BAR1-1-12 matches 1,1,1,12.
*/
private static final Pattern NUMBERS = Pattern.compile("(\\d+)");
static List<Integer> extractNumbersViaRegEx(final String source) {
final Matcher matcher = NUMBERS.matcher(source);
final List<Integer> result = new ArrayList<Integer>();
if (matcher.find()) {
do {
result.add(Integer.parseInt(matcher.group(0)));
} while (matcher.find());
return result;
}
return result;
}
}