views:

3295

answers:

5

I have to write huge data in text[csv] file. I used BufferedWriter to write the data and it took around 40 secs to write 174 mb of data. Is this the fastest speed java can offer?

bufferedWriter = new BufferedWriter ( new FileWriter ( "fileName.csv" ) );

Note: These 40 secs include the time of iterating and fetching the records from resultset as well. :) . 174 mb is for 400000 rows in resultset.

+2  A: 

Your transfer speed is likely not to be limited by Java. Instead I would suspect (in no particular order)

  1. the speed of transfer from the database
  2. the speed of transfer to the disk

If you read the complete dataset and then write it out to disk, then that will take longer, since the JVM will have to allocate memory, and the db rea/disk write will happen sequentially. Instead I would write out to the buffered writer for every read that you make from the db, and so the operation will be closer to a concurrent one (I don't know if you're doing that or not)

Brian Agnew
+7  A: 

You might try removing the BufferedWriter and just using the FileWriter directly. On a modern system there's a good chance you're just writing to the drive's cache memory anyway.

It takes me in the range of 4-5 seconds to write 175MB (4 million strings) -- this is on a dual-core 2.4GHz Dell running Windows XP with an 80GB, 7200-RPM Hitachi disk.

Can you isolate how much of the time is record retrieval and how much is file writing?

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

public class FileWritingPerfTest {


private static final int ITERATIONS = 5;
private static final double MEG = (Math.pow(1024, 2));
private static final int RECORD_COUNT = 4000000;
private static final String RECORD = "Help I am trapped in a fortune cookie factory\n";
private static final int RECSIZE = RECORD.getBytes().length;

public static void main(String[] args) throws Exception {
 List<String> records = new ArrayList<String>(RECORD_COUNT);
 int size = 0;
 for (int i = 0; i < RECORD_COUNT; i++) {
  records.add(RECORD);
  size += RECSIZE;
 }
 System.out.println(records.size() + " 'records'");
 System.out.println(size / MEG + " MB");

 for (int i = 0; i < ITERATIONS; i++) {
  System.out.println("\nIteration " + i);

  writeRaw(records);
  writeBuffered(records, 8192);
  writeBuffered(records, (int) MEG);
  writeBuffered(records, 4 * (int) MEG);
 }
}

private static void writeRaw(List<String> records) throws IOException {
 File file = File.createTempFile("foo", ".txt");
 FileWriter writer = new FileWriter(file);

 System.out.print("Writing raw... ");
 write(records, writer);
}

private static void writeBuffered(List<String> records, int bufSize) throws IOException {
 File file = File.createTempFile("foo", ".txt");
 FileWriter writer = new FileWriter(file);
 BufferedWriter bufferedWriter = new BufferedWriter(writer, bufSize);

 System.out.print("Writing buffered (buffer size: " + bufSize + ")... ");
 write(records, bufferedWriter);
}

private static void write(List<String> records, Writer writer) throws IOException {
 long start = System.currentTimeMillis();
 for (String record: records) {
  writer.write(record);
 }
 writer.flush();
 writer.close();
 long end = System.currentTimeMillis();
 System.out.println((end - start) / 1000f + " seconds");
}
}
David Moles
+1 for the example :D
Rakesh Juyal
No problem. :)
David Moles
A: 

For these bulky reads from DB you may want to tune your Statement's fetch size. It might save a lot of roundtrips to DB.

http://download.oracle.com/javase/1.5.0/docs/api/java/sql/Statement.html#setFetchSize%28int%29

gpeche