Your indentation is on the limit of being hard to read! :p Usually there's more indentation between two nested things. Ex :
Your code :
if(true)
{
if(true && 1==1)
{
}
}
Usually :
if(true)
{
if(true && 1==1)
{
}
}
It is much easier to read this way! Also, Java conventions point that the bracket's style should be "egyptian" meaning :
if(...) {
}
instead of
if(...)
{
}
You could reduce the nesting (and hence enhance readability) by reversing the logic of your first if
. Instead of :
if(text != null) {
}
You should write :
if(text == null) {
return result;
}
This way there's less code in your if
, and well, that's easier to read.
Another way to remove the else
code block would be to introduce a variable that checks if the current character is a separator.
Same thing for n > 0
. Although you could simply drop this condition. If n==0
, then your for
loop simply won't be executed and "voilà", you return result
.
Look at this : boolean y = false; // "preceding char is separator" flag
If you have a comment explaining what your variable does, then your variable isn't well named. Why wouldn't you name your boolean precedingCharIsSeparator
? Is it too long? I don't think so, plus it would mean the comment is now useless, you could remove it. Remember that long variable names aren't longer to compute! :p
The overall naming needs to be reviewed. It won't help for performance, but it will sure as hell help for readability, which is the second biggest concern of your code.
There's something you need to understand about profiling. The final result will always be 100%. The fact that your code takes 58% of the time isn't abnormal. It could be 58% of 1 millisecond or 58% of 10 minutes. If the bottleneck of your application is split
, your application is probably fine. Otherwise you maybe need to check if you can replace your split
by something else.
Here's the final code, with better named variables, less nesting and the usage of a char[]
which I think will speed up a little bit your code. (But I have no proof of what I'm saying! :p)
private static List<String> fastSplitWS(final String text)
{
final List<String> result = new ArrayList<String>();
if(text == null) {
return result;
}
final char[] characters = text.toCharArray();
final int length = characters.length;
int newWordIndex = 0;
boolean precedingCharIsSeparator = true;
for(int i = 0; i < length; i++) {
char current = characters[i];
boolean currentCharIsSeparator = current == '\t' || current == ' ';
if(currentCharIsSeparator && !precedingCharIsSeparator) {
result.add(new String(characters, newWordIndex, i - newWordIndex + 1));
} else if(precedingCharIsSeparator) {
newWordIndex = i;
}
precedingCharIsSeparator = currentCharIsSeparator;
}
if(newWordIndex < length - 1) {
result.add(new String(characters, newWordIndex, length - newWordIndex));
}
return result;
}
Finally, the method name isn't very good. I guess WS
stands for WhiteSpace
, well you should write it fully! splitOnWhitespace
would be a better name.
Finally (again lol), you should wonder if you really want to return a List<String>
? Usually split
returns an array, I think it should be the same here.
\s
covers more white space chars than just space and tab... If you only need these 2, an own implementation might be faster, otherwise don't compete with libraries :). \$\endgroup\$if
with the full set of whitespace characters) and then chose tab and space because other variants are eliminated in this specific place. But I'm not sure that adding one more condition will slow down my code a lot, and if not - it will remain 2 times faster thansplit("\\s+")
. So your remark about useless competition can be incorrect. \$\endgroup\$