0

I'm trying to create a JSON-like format to load components from files and while writing the parser I've run into an interesting performance question.

The parser reads the file character by character, so I have a LinkedList as a buffer. After reaching the end of a key (:) or a value (,) the buffer has to be emptied and a string constructed of it.

My question is what is the most efficient way to do this.

My two best bets would be:

for (int i = 0; i < buff.size(); i++)
    value += buff.removeFirst().toString();

and

value = new String((char[]) buff.toArray(new char[buff.size()]));
  • Go with the `BufferedReader` class... here there are too many memory allocations not to say that reading a file character by character is **really** slow – Some random IT boy Jul 18 '19 at 20:49
  • 1
    A LinkedList seems like a very cumbersome choice. Is there a good reason to use this, rather than, say, StringBuilder? – Andy Turner Jul 18 '19 at 21:04
  • Also, note that the for loop will only add half the characters into the list. You should use `while (!buff.isEmpty())` instead. – Andy Turner Jul 18 '19 at 22:07

1 Answers1

0

Instead of guessing this you should write a benchmark. Take a look at How do I write a correct micro-benchmark in Java to understand how to write a benchmark with JMH.

Your for loop would be inefficient as you are concatenating 1-letter Strings using + operator. This leads to creation and immediate throwing away intermediate String objects. You should use StringBuilder if you plan to concatenate in a loop.

The second option should use a zero-length array as per Arrays of Wisdom of the Ancients article which dives into internal details of the JVM:

value = new String((char[]) buff.toArray(new char[0]));
Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111