3

In the code below, which case (1 or 2) is more "efficient"?

static final String NEWLINE = System.getProperty("line.separator"); Vector<String> text_vec = ...; FileWriter file_writer = new FileWriter(path); BufferedWriter buffered_writer = new BufferedWriter(file_writer); try { for (String text: text_vec) { // Case 1: String concatenation buffered_writer.write(text + NEWLINE); // Case 2: Extra call to write() buffered_writer.write(text); buffered_writer.write(NEWLINE); } } finally { buffered_writer.close(); } 

In case #1, as I understand, the String concatenation is handled by the Java compiler by automatically allocating a StringBuilder object. Since the String values are not known at compile time, it is not possible to concatenate "early" (during compile time).

So the question stands: Which one is more efficient (CPU/memory/wall clock time)?

I am leaving the exact definition of "efficient" to those whom answer. I am not an expert on the Java virtual machine.

4 Answers 4

4

Unless you benchmark it and prove that you have a good reason not to, you should write directly to the buffer. It's there to provide an efficient method for writing to a file.

Also, don't forget to flush the buffer when you're done writing to it.

Sign up to request clarification or add additional context in comments.

1 Comment

AFAIK, closing automatically flushes the underlying streams so flushing is rarely required.
1

The second one should be faster as its preventing useless String object creation, this is because BufferedWriter writes directly converts its input to bytes/characters, instead of creating useless string objects.

With case 1:

Your code makes:

1 time StringBuilder; (Implied by appending Strings together)

1 time String; (Implied by appending Strings together)

1 time char[]; By the buffered writer

With case 2:

Your code makes:

2 time char[]; By the buffered writer


Since the last case makes less objects, and less large objects, this should be faster.

Comments

0

File IO is orders of magnitude slower than anything you do with String concatenation in a JVM. The disk will be your bottleneck no matter what.

This assumes we aren't talking about an SSD, which probably still slower than the JVM itself.

EDIT: Clearly not communicating well based on comments. Lemme try in a larger text box. OP indicated a FileWriter. This means eventually all data must go to disk. Disk latency is measured in milliseconds and throughput in megabytes/second, usually 10s, but not 100s.

Memory latency is measured in nanoseconds and throughput in Gigabytes per second. Most of your string concatenation takes place there. This is 3-6 orders of magnitude faster than the disk.

Regardless of how you buffer, concatenate etc, eventually you will run into the throughput limitations of the disk. Most especially if you flush() and wait for it to actually finish flushing to the media.

Buffering doesn't mean squat other than making the disk IO more efficient. Yes, you should use a buffer when writing, something on the order of 1k-16k is plenty. However, that buffer will NOT change the throughput of your disk. Which is orders of magnitude slower than your string concatenation problem.

So. If you want to talk about efficiency when writing to the disk, forget about how you concatenate strings. Just make it easy to read code.

3 Comments

He's not writing directly to a file, he's writing to a buffer.
He's going to write to that file whether the data is temporarily stored in a String or in a buffer. It makes no difference.
The point of my first comment is that writing to a buffer is not orders of magnitude slower than String concatenation.
0

It all goes through a buffer, so there should be little difference. Probably version 2 with the extra write is faster.

But unless you are doing this a gazillion times it wont matter.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.