Saya memiliki CSV
file 35GB . Saya ingin membaca setiap baris, dan menulis baris ke CSV baru jika cocok dengan suatu syarat.
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");
});
}
}
Ini membutuhkan sekitar. 7 menit. Apakah mungkin untuk mempercepat proses itu lebih banyak lagi?
java
java-stream
java-io
anggota
sumber
sumber
parallel
membuatnya lebih cepat? Dan bukankah itu mengocok garis sekitar?BufferedWriter
diri Anda sendiri, menggunakan konstruktor yang memungkinkan Anda mengatur ukuran buffer. Mungkin ukuran buffer yang lebih besar (atau lebih kecil) akan membuat perbedaan. Saya akan mencoba mencocokkanBufferedWriter
ukuran buffer dengan ukuran buffer sistem operasi host.Jawaban:
Jika ini merupakan opsi, Anda dapat menggunakan GZipInputStream / GZipOutputStream untuk meminimalkan I / O disk.
Files.newBufferedReader / Writer menggunakan ukuran buffer default, 8 KB saya percaya. Anda dapat mencoba buffer yang lebih besar.
Konversi ke String, Unicode, melambat ke (dan menggunakan memori dua kali). UTF-8 yang digunakan tidak sesederhana StandardCharsets.ISO_8859_1.
Yang terbaik adalah jika Anda dapat bekerja dengan byte untuk sebagian besar dan hanya untuk bidang CSV spesifik mengubahnya menjadi String.
File yang dipetakan memori mungkin yang paling tepat. Paralelisme dapat digunakan oleh rentang file, meludah file.
Ini akan menjadi kode yang sedikit banyak, mendapatkan garis yang benar
(byte)'\n'
, tetapi tidak terlalu rumit.sumber
GZipInputStream + GZipOutputStream
sepenuhnya memori pada ramdisk. Kinerja jauh lebih buruk ...MappedByteBuffer
dari posisi terakhir yang diketahui baik (FileChannel.map
butuh waktu lama).new RandomAccessFile(…).getChannel()
. Gunakan sajaFileChannel.open(…)
.Anda dapat mencoba ini:
Saya pikir itu akan menghemat satu atau dua menit. tes dapat dilakukan pada mesin saya dalam waktu sekitar 4 menit dengan menentukan ukuran buffer.
mungkinkah lebih cepat? coba ini:
Ini akan menghemat waktu Anda tiga atau empat menit.
Jika itu masih belum cukup. (Alasan saya kira Anda mengajukan pertanyaan mungkin adalah Anda perlu menjalankan tugas berulang kali). jika Anda ingin menyelesaikannya dalam satu menit atau bahkan beberapa detik. maka Anda harus memproses data dan menyimpannya ke db, lalu memproses tugas dengan beberapa server.
sumber
cbuf
konten, dan hanya menulis bagian? Dan apakah saya harus mengatur ulang buffer setelah penuh? (bagaimana saya bisa tahu buffer sudah penuh?)Terima kasih atas semua saran Anda, yang tercepat saya dapatkan adalah menukar penulis
BufferedOutputStream
, yang memberikan peningkatan sekitar 25%:Tetap
BufferedReader
berkinerja lebih baik daripadaBufferedInputStream
dalam kasus saya.sumber