Вы можете попробовать что-то вроде этого:
public class NGram {
private final int n;
private final String text;
private final int[] indexes;
private int index = -1;
private int found = 0;
public NGram(String text, int n) {
this.text = text;
this.n = n;
indexes = new int[n];
}
private boolean seek() {
if (index >= text.length()) {
return false;
}
push();
while(++index < text.length()) {
if (text.charAt(index) == ' ') {
found++;
if (found<n) {
push();
} else {
return true;
}
}
}
return true;
}
private void push() {
for (int i = 0; i < n-1; i++) {
indexes[i] = indexes[i+1];
}
indexes[n-1] = index+1;
}
private List<String> list() {
List<String> ngrams = new ArrayList<String>();
while (seek()) {
ngrams.add(get());
}
return ngrams;
}
private String get() {
return text.substring(indexes[0], index);
}
}
Тестирование около 5 Мб текста, кажется, работает примерно в 10 раз быстрее, чем исходный код. Основное отличие состоит в том, что регулярное выражение не используется для разделения, а строки ngram не создаются путем конкатенации.
Обновление:
Это вывод, который я получаю, работая над текстом, упомянутым выше, ngram 1-4. Я использую 2 ГБ памяти, чтобы определить влияние на сборку во время пробежек. Я запускал несколько раз, чтобы увидеть влияние компилятора горячей точки.
Loop 01 Code mine ngram 1 time 071ms ngrams 294121
Loop 01 Code orig ngram 1 time 534ms ngrams 294121
Loop 01 Code mine ngram 2 time 016ms ngrams 294120
Loop 01 Code orig ngram 2 time 360ms ngrams 294120
Loop 01 Code mine ngram 3 time 082ms ngrams 294119
Loop 01 Code orig ngram 3 time 319ms ngrams 294119
Loop 01 Code mine ngram 4 time 014ms ngrams 294118
Loop 01 Code orig ngram 4 time 439ms ngrams 294118
Loop 10 Code mine ngram 1 time 013ms ngrams 294121
Loop 10 Code orig ngram 1 time 268ms ngrams 294121
Loop 10 Code mine ngram 2 time 014ms ngrams 294120
Loop 10 Code orig ngram 2 time 323ms ngrams 294120
Loop 10 Code mine ngram 3 time 013ms ngrams 294119
Loop 10 Code orig ngram 3 time 412ms ngrams 294119
Loop 10 Code mine ngram 4 time 014ms ngrams 294118
Loop 10 Code orig ngram 4 time 423ms ngrams 294118