First off, every answer should be subject to testing in production conditions. When performance is the question, RAM and cache sizes, bus speeds etc. come into play and make things hard to predict. Another question is how many times will this code run - the JVM will initially run an interpreted version of it, and only after the code has been executed enough times will replace that with a compiled (and faster) version.
Having said that, here are some pointers:
- If you have a lot of keywords, consider parallelizing the task. Use an executor, or a parallel stream. That would only work for about 100+ keywords, and make your code slower for smaller amounts of keywords.
- If the keywords are used often enough, try using some algorithm to search all of them, e.g. using a prefix-tree (a.k.a. trie). Note that these structures can cause inefficient memory use, as the node objects may be scattered in memory and thus cause cache misses while being traversed. This is why an ArrayList is faster than a LinkedList in practice, even though they have the similar properties in theory.
- Try switching to byte arrays (i.e. using String.getBytes), and then using the methods of
Arrays
class to find each word. This has the advantage of memory locality. Note that Unicode may be tricky here, so you may need to normalize
it first.
But above all, test. Just make sure you're doing your micro-benchmarks properly.