kzen.dev
  • Pertanyaan
  • Tag
  • Pengguna
Notifikasi
Imbalan
Registrasi
Setelah Anda mendaftar, Anda akan diberitahu tentang balasan dan komentar untuk pertanyaan Anda.
Gabung
Jika Anda sudah memiliki akun, masuk untuk memeriksa pemberitahuan baru.
Akan ada hadiah untuk pertanyaan, jawaban, dan komentar tambahan.
Lebih
Sumber
Sunting
 user1785771
user1785771
Question

Cara Tercepat Untuk Membaca dan Menulis File Besar Baris Demi Baris di Java

Saya telah banyak mencari cara tercepat untuk membaca dan menulis lagi file besar (0,5 - 1 GB) di java dengan memori terbatas (sekitar 64MB). Setiap baris dalam file mewakili sebuah catatan, jadi saya perlu mendapatkannya baris demi baris. File tersebut adalah file teks biasa.

Saya mencoba BufferedReader dan BufferedWriter tetapi tampaknya bukan pilihan terbaik. Dibutuhkan sekitar 35 detik untuk membaca dan menulis file berukuran 0.5 GB, hanya baca tulis tanpa pemrosesan. Saya pikir bottleneck di sini adalah menulis karena membaca saja membutuhkan waktu sekitar 10 detik.

Saya mencoba membaca array byte, tetapi kemudian mencari baris di setiap array yang dibaca membutuhkan lebih banyak waktu.

Ada saran yang bisa diberikan? Terima kasih

19 2012-10-31T10:19:02+00:00 3
Peter Lawrey
Peter Lawrey
Pertanyaan edit 10 April 2016 в 1:37
Pemrograman
java
performance
file-io
bufferedreader
Pertanyaan ini memiliki :value jawaban dalam bahasa Inggris, untuk membacanya masuk ke akun Anda.
Solution / Answer
Peter Lawrey
Peter Lawrey
31 Oktober 2012 в 10:52
2012-10-31T10:52:36+00:00
Lebih
Sumber
Sunting
#17602954

Saya menduga masalah Anda yang sebenarnya adalah bahwa Anda memiliki perangkat keras yang terbatas dan apa yang Anda lakukan adalah perangkat lunak tidak akan membuat banyak perbedaan. Jika Anda memiliki banyak memori dan CPU, trik yang lebih canggih dapat membantu, tetapi jika Anda hanya menunggu di hard drive Anda karena file tidak di-cache, itu tidak akan membuat banyak perbedaan.

BTW: 500 MB dalam 10 detik atau 50 MB/detik adalah kecepatan baca yang umum untuk HDD.

Coba jalankan yang berikut ini untuk melihat pada titik mana sistem Anda tidak dapat men-cache file secara efisien.

public static void main(String... args) throws IOException {
    for (int mb : new int[]{50, 100, 250, 500, 1000, 2000})
        testFileSize(mb);
}

private static void testFileSize(int mb) throws IOException {
    File file = File.createTempFile("test", ".txt");
    file.deleteOnExit();
    char[] chars = new char[1024];
    Arrays.fill(chars, 'A');
    String longLine = new String(chars);
    long start1 = System.nanoTime();
    PrintWriter pw = new PrintWriter(new FileWriter(file));
    for (int i = 0; i < mb * 1024; i++)
        pw.println(longLine);
    pw.close();
    long time1 = System.nanoTime() - start1;
    System.out.printf("Took %.3f seconds to write to a %d MB, file rate: %.1f MB/s%n",
            time1 / 1e9, file.length() >> 20, file.length() * 1000.0 / time1);

    long start2 = System.nanoTime();
    BufferedReader br = new BufferedReader(new FileReader(file));
    for (String line; (line = br.readLine()) != null; ) {
    }
    br.close();
    long time2 = System.nanoTime() - start2;
    System.out.printf("Took %.3f seconds to read to a %d MB file, rate: %.1f MB/s%n",
            time2 / 1e9, file.length() >> 20, file.length() * 1000.0 / time2);
    file.delete();
}

Pada mesin Linux dengan banyak memori.

Took 0.395 seconds to write to a 50 MB, file rate: 133.0 MB/s
Took 0.375 seconds to read to a 50 MB file, rate: 140.0 MB/s
Took 0.669 seconds to write to a 100 MB, file rate: 156.9 MB/s
Took 0.569 seconds to read to a 100 MB file, rate: 184.6 MB/s
Took 1.585 seconds to write to a 250 MB, file rate: 165.5 MB/s
Took 1.274 seconds to read to a 250 MB file, rate: 206.0 MB/s
Took 2.513 seconds to write to a 500 MB, file rate: 208.8 MB/s
Took 2.332 seconds to read to a 500 MB file, rate: 225.1 MB/s
Took 5.094 seconds to write to a 1000 MB, file rate: 206.0 MB/s
Took 5.041 seconds to read to a 1000 MB file, rate: 208.2 MB/s
Took 11.509 seconds to write to a 2001 MB, file rate: 182.4 MB/s
Took 9.681 seconds to read to a 2001 MB file, rate: 216.8 MB/s

Pada mesin windows dengan banyak memori.

Took 0.376 seconds to write to a 50 MB, file rate: 139.7 MB/s
Took 0.401 seconds to read to a 50 MB file, rate: 131.1 MB/s
Took 0.517 seconds to write to a 100 MB, file rate: 203.1 MB/s
Took 0.520 seconds to read to a 100 MB file, rate: 201.9 MB/s
Took 1.344 seconds to write to a 250 MB, file rate: 195.4 MB/s
Took 1.387 seconds to read to a 250 MB file, rate: 189.4 MB/s
Took 2.368 seconds to write to a 500 MB, file rate: 221.8 MB/s
Took 2.454 seconds to read to a 500 MB file, rate: 214.1 MB/s
Took 4.985 seconds to write to a 1001 MB, file rate: 210.7 MB/s
Took 5.132 seconds to read to a 1001 MB file, rate: 204.7 MB/s
Took 10.276 seconds to write to a 2003 MB, file rate: 204.5 MB/s
Took 9.964 seconds to read to a 2003 MB file, rate: 210.9 MB/s
16
0
 jarnbjo
jarnbjo
31 Oktober 2012 в 12:48
2012-10-31T12:48:10+00:00
Lebih
Sumber
Sunting
#17602955

Hal pertama yang akan saya coba adalah meningkatkan ukuran buffer dari BufferedReader dan BufferedWriter. Ukuran buffer default tidak didokumentasikan, tetapi setidaknya di Oracle VM ukurannya adalah 8192 karakter, yang tidak akan membawa banyak keuntungan kinerja.

Jika Anda hanya perlu membuat salinan file (dan tidak memerlukan akses aktual ke data), saya akan membuang pendekatan Reader/Writer dan bekerja secara langsung dengan InputStream dan OutputStream menggunakan array byte sebagai buffer:

FileInputStream fis = new FileInputStream("d:/test.txt");
FileOutputStream fos = new FileOutputStream("d:/test2.txt");
byte[] b = new byte[bufferSize];
int r;
while ((r=fis.read(b))>=0) {
    fos.write(b, 0, r);         
}
fis.close();
fos.close();

atau benar-benar menggunakan NIO:

FileChannel in = new RandomAccessFile("d:/test.txt", "r").getChannel();
FileChannel out = new RandomAccessFile("d:/test2.txt", "rw").getChannel();
out.transferFrom(in, 0, Long.MAX_VALUE);
in.close();
out.close();

Ketika melakukan benchmarking metode penyalinan yang berbeda, saya memiliki perbedaan (durasi) yang jauh lebih besar di antara setiap menjalankan benchmark daripada di antara implementasi yang berbeda. I/O caching (baik pada level OS dan cache hard disk) memainkan peran besar di sini dan sangat sulit untuk mengatakan mana yang lebih cepat. Pada perangkat keras saya, menyalin file teks 1GB baris demi baris menggunakan BufferedReader dan BufferedWriter membutuhkan waktu kurang dari 5 detik di beberapa proses dan lebih dari 30 detik di proses lainnya.

 jarnbjo
jarnbjo
Jawaban edit 31 Oktober 2012 в 1:00
9
0
 duffymo
duffymo
31 Oktober 2012 в 10:23
2012-10-31T10:23:39+00:00
Lebih
Sumber
Sunting
#17602953

Saya akan merekomendasikan untuk melihat kelas-kelas dalam paket java.nio. IO non-blocking mungkin lebih cepat untuk soket:

http://docs.oracle.com/javase/6/docs/api/java/nio/package-summary.html

Artikel ini memiliki tolok ukur yang mengatakan bahwa itu benar:

http://vanillajava.blogspot.com/2010/07/java-nio-is-faster-than-java-io-for.html

2
0
Related communities 3
Programmer JAVA indonesia
Programmer JAVA indonesia
1 757 pengguna
Buka telegram
jvmusergroup
jvmusergroup
354 pengguna
Bismillahirrohmanirohim. Perhatian! Grup ini merupakan ekspansi dari grup Forum Java Programmer Indonesia di Facebook. Silahkan berbagi pengalaman dan masalah seputar Java dan keluarganya. https://t.me/JVMIndonesia Admin : @hendisantika34
Buka telegram
Java Indonesia🇲🇨
Java Indonesia🇲🇨
153 pengguna
Programmer Java Indonesia. Grup ini digunakan untuk bertanya terkait materi belajar Java / fullstack Warning=> -dilarang promosi(izin adm -18+🔞 - berbicara sopan - no spam /boot Mohon ikut aturan grup belum di keluarkan
Buka telegram
Tambahkan pertanyaan
Kategori
Semua
Teknologi
Budaya / Rekreasi
Kehidupan / Seni
Ilmu Pengetahuan
Profesional
Bisnis
Pengguna
Semua
Baru
Populer
1
工藤 芳則
Terdaftar 6 hari yang lalu
2
Ирина Беляева
Terdaftar 1 minggu yang lalu
3
Darya Arsenyeva
Terdaftar 1 minggu yang lalu
4
anyta nuam-nuam (LapuSiK)
Terdaftar 1 minggu yang lalu
5
Shuhratjon Imomkulov
Terdaftar 1 minggu yang lalu
ID
JA
KO
© kzen.dev 2023
Sumber
stackoverflow.com
di bawah lisensi cc by-sa 3.0 dengan atribusi