У меня есть CSV
файл 35 ГБ . Я хочу прочитать каждую строку и записать строку в новый CSV, если он соответствует условию.
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get("source.csv"))) {
try (BufferedReader br = Files.newBufferedReader(Paths.get("target.csv"))) {
br.lines().parallel()
.filter(line -> StringUtils.isNotBlank(line)) //bit more complex in real world
.forEach(line -> {
writer.write(line + "\n");
});
}
}
Это занимает ок. 7 минут Можно ли еще быстрее ускорить этот процесс?
java
java-stream
java-io
membersound
источник
источник
parallel
делает это быстрее? И разве это не перемешивает линии?BufferedWriter
себя, используя конструктор, который позволяет вам установить размер буфера. Возможно, больший (или меньший) размер буфера будет иметь значение. Я хотел бы попытаться сопоставитьBufferedWriter
размер буфера с размером буфера операционной системы хоста.Ответы:
Если это опция, вы можете использовать GZipInputStream / GZipOutputStream для минимизации дискового ввода-вывода.
Files.newBufferedReader / Writer использует размер буфера по умолчанию, я полагаю, 8 КБ. Вы можете попробовать больший буфер.
Преобразование в строку, Unicode, замедляется (и использует в два раза больше памяти). Используемый UTF-8 не так прост, как StandardCharsets.ISO_8859_1.
Лучше всего, если вы можете работать с байтами по большей части и только для определенных CSV-полей конвертировать их в String.
Файл сопоставления памяти может быть наиболее подходящим. Параллелизм может использоваться диапазонами файлов, выплевывая файл.
Это станет немного больше кода, получая строки прямо
(byte)'\n'
, но не слишком сложным.источник
GZipInputStream + GZipOutputStream
полностью память на виртуальном диске. Производительность была намного хуже ...MappedByteBuffer
из последней заведомо хорошей позиции (FileChannel.map
занимает много времени).new RandomAccessFile(…).getChannel()
. Просто используйтеFileChannel.open(…)
.Вы можете попробовать это:
Я думаю, что это сэкономит вам одну или две минуты. Тест можно выполнить на моей машине примерно за 4 минуты, указав размер буфера.
это может быть быстрее? попробуй это:
Это должно сэкономить вам три или четыре минуты.
Если этого еще недостаточно. (Вероятно, причина, по которой вы задаете вопрос, заключается в том, что вам нужно выполнять задачу повторно). если вы хотите сделать это за одну минуту или даже пару секунд. Затем вы должны обработать данные и сохранить их в БД, а затем обработать задачу несколькими серверами.
источник
cbuf
содержимое и выписать только порции? И должен ли я сбросить буфер после заполнения? (как я могу знать , что буфер заполнен?)Благодаря всем вашим предложениям быстрее всего я обменивался писателем
BufferedOutputStream
, что дало улучшение примерно на 25%:Тем не менее,
BufferedReader
работает лучше, чемBufferedInputStream
в моем случае.источник