Самый быстрый способ записать огромные данные в Java текстового файла

GNU tar имеет полезную опцию, которая дает функциональность простого индикатора выполнения.

(...) Другое доступное действие контрольной точки - «точка» (или «.»). Он указывает tar печатать одну точку в стандартном потоке листинга, например :

$ tar -c --checkpoint=1000 --checkpoint-action=dot /var
...

Тот же эффект может быть получен с помощью:

$ tar -c --checkpoint=.1000 /var

64
задан Rakesh Juyal 30 June 2009 в 06:57
поделиться

3 ответа

Вы можете попробовать удалить BufferedWriter и просто использовать FileWriter напрямую. В современной системе велика вероятность, что вы все равно просто записываете в кэш-память накопителя.

На запись 175 МБ (4 миллиона строк) у меня уходит от 4 до 5 секунд - это на двойном диске. ядро 2,4 ГГц Dell работает под управлением Windows XP с диском Hitachi 80 ГБ, 7200 об / мин.

Можете ли вы выделить, сколько времени занимает извлечение записей, а сколько - запись файлов?

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");
    try {
        FileWriter writer = new FileWriter(file);
        System.out.print("Writing raw... ");
        write(records, writer);
    } finally {
        // comment this out if you want to inspect the files afterward
        file.delete();
    }
}

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

        System.out.print("Writing buffered (buffer size: " + bufSize + ")... ");
        write(records, bufferedWriter);
    } finally {
        // comment this out if you want to inspect the files afterward
        file.delete();
    }
}

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");
}
}
96
ответ дан 24 November 2019 в 15:44
поделиться

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)

5
ответ дан 24 November 2019 в 15:44
поделиться

Для этих громоздких чтений из БД вы можете настроить размер выборки оператора. Это может сэкономить много обращений к БД.

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

4
ответ дан 24 November 2019 в 15:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: