I am trying to implement JLanguageTool in combination with JavaFX and RichtextFX to get myself a GUI which spellchecks the given input in a Codearea
and highlights misspelled words. My problem is, that even for small sentences (6 words) with a little amount of misspells (3 misspells) my program takes 10-12 seconds to execute(only the spellchecking part). I've already tried optimizing my program by deactivating rules that are not neccessary for me. Here's my code:
import org.languagetool.JLanguageTool;
import org.languagetool.language.GermanyGerman;
import org.languagetool.rules.Category;
import org.languagetool.rules.CategoryId;
import org.languagetool.rules.RuleMatch;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LanguageToolTest {
private static JLanguageTool tool = new JLanguageTool(new GermanyGerman());
public static void prepareRule(){
Map <CategoryId, Category> akku = tool.getCategories();
for (var entry : akku.entrySet()){
if (!entry.getKey().toString().contains("EMPFOHLENE_RECHTSCHREIBUNG")
&& !entry.getKey().toString().contains("CASING")
&& !entry.getKey().toString().contains("TYPOS")
&& !entry.getKey().toString().contains("COMPOUNDING")
&& !entry.getKey().toString().contains("PUNCTUATION")
&& !entry.getKey().toString().contains("CONFUSED_WORDS")
&& !entry.getKey().toString().contains("SEMANTICS")){
tool.disableCategory(entry.getKey());
}
}
}
public static void main(String[] args) {
prepareRule();
Instant start = Instant.now();
Map<Integer, List<String>> test = new HashMap<>();
int index = 0;
try {
List<RuleMatch> matches = tool.check("Heilike makrele hier ist echter Tecst");
for (RuleMatch match : matches){
List<String> temp = new ArrayList<>();
index = match.getFromPos();
int end = match.getToPos();
String idk = "Heilike makrele hier ist echter Tecst".substring(index, end);
temp.add(idk);
temp.addAll(match.getSuggestedReplacements());
test.put(match.getFromPos(), temp);
}
Instant stop = Instant.now();
Duration timeElapsed = Duration.between(start, stop);
System.out.println(test.toString());
System.out.println("Hat " + timeElapsed.toMillis() + " Millisekunden gedauert.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
And the output:
{0=[Heilike, Heilige, Heiligen, Heidecke, Heilig, Heinicke, Heiliger, Heiliges, Heiligem, Beilage, Heiligt, Heike, Heiligte, Fällige, Herlocke, Heutige, Wellige, Heftige, Eilige, Häufige, Seidige], 32=[Tecst, Eckt, Deckt, Test, Täks, Deckst, Erst, Teast, Lässt, Des, Meist, Fest, Heißt, Jetzt, Setzt, Weist, Recht, Text, West, Wächst, Geist], 8=[makrele, Makrele, makele, mäkele, sakrale, magere, mangele, Makrelen, Nägele, Häcksel, Häckseln, angele, dackele, fackele, fächele, hagele, häckseln, häkele, lächele, magerere, magerte]}
Hat 12483 Millisekunden gedauert.
To explain the Map: my Key
stores the start index of the found error for further processing and the List
value stores a list of the misspelled word at index 0 and recommended replacements on the following indecies.
In my actual code the Map gets returned and processed for the highlighting part.
As far as I understood the documentation of JLanguageTool it's not thread-safe therefore I can't multithread it.
Any suggestions on how to improve my code/optimize certain calls to reduce the performance impact?