Saya ingin membaca file teks baris demi baris. Saya ingin tahu apakah saya melakukannya seefisien mungkin dalam lingkup .NET C #.
Inilah yang saya coba sejauh ini:
var filestream = new System.IO.FileStream(textFilePath,
System.IO.FileMode.Open,
System.IO.FileAccess.Read,
System.IO.FileShare.ReadWrite);
var file = new System.IO.StreamReader(filestream, System.Text.Encoding.UTF8, true, 128);
while ((lineOfText = file.ReadLine()) != null)
{
//Do something with the lineOfText
}
c#
.net
performance
file-io
text-files
Loren C Fortner
sumber
sumber
Fastest
maksud dari kinerja atau pengembangan perspektif?filestream = new FileStream
dalamusing()
pernyataan untuk menghindari kemungkinan masalah yang mengganggu dengan penguncian file yang dikunciJawaban:
Untuk menemukan cara tercepat untuk membaca file baris demi baris, Anda harus melakukan benchmarking. Saya telah melakukan beberapa tes kecil di komputer saya, tetapi Anda tidak dapat berharap bahwa hasil saya berlaku untuk lingkungan Anda.
Menggunakan StreamReader.ReadLine
Ini pada dasarnya metode Anda. Untuk beberapa alasan Anda mengatur ukuran buffer ke nilai sekecil mungkin (128). Peningkatan ini secara umum akan meningkatkan kinerja. Ukuran default adalah 1.024 dan pilihan bagus lainnya adalah 512 (ukuran sektor di Windows) atau 4.096 (ukuran kluster di NTFS). Anda harus menjalankan patokan untuk menentukan ukuran buffer optimal. Buffer yang lebih besar adalah - jika tidak lebih cepat - setidaknya tidak lebih lambat dari buffer yang lebih kecil.
The
FileStream
konstruktor memungkinkan Anda untuk menentukan FileOptions . Misalnya, jika Anda membaca file besar secara berurutan dari awal hingga akhir, Anda dapat mengambil manfaat dariFileOptions.SequentialScan
. Sekali lagi, pembandingan adalah hal terbaik yang dapat Anda lakukan.Menggunakan File.ReadLines
Ini sangat mirip dengan solusi Anda sendiri kecuali itu diimplementasikan menggunakan
StreamReader
dengan ukuran buffer tetap 1.024. Di komputer saya ini menghasilkan kinerja yang sedikit lebih baik dibandingkan dengan kode Anda dengan ukuran buffer 128. Namun, Anda bisa mendapatkan peningkatan kinerja yang sama dengan menggunakan ukuran buffer yang lebih besar. Metode ini diimplementasikan menggunakan blok iterator dan tidak mengkonsumsi memori untuk semua lini.Menggunakan File.ReadAllLines
Ini sangat mirip dengan metode sebelumnya kecuali bahwa metode ini menumbuhkan daftar string yang digunakan untuk membuat array garis yang dikembalikan sehingga persyaratan memori lebih tinggi. Namun, ia kembali
String[]
dan tidakIEnumerable<String>
memungkinkan Anda mengakses jalur secara acak.Menggunakan String.Split
Metode ini jauh lebih lambat, setidaknya pada file besar (diuji pada file 511 KB), mungkin karena cara
String.Split
diimplementasikan. Ini juga mengalokasikan array untuk semua baris yang meningkatkan memori yang diperlukan dibandingkan dengan solusi Anda.Saran saya adalah menggunakan
File.ReadLines
karena bersih dan efisien. Jika Anda memerlukan opsi berbagi khusus (misalnya Anda menggunakanFileShare.ReadWrite
), Anda dapat menggunakan kode Anda sendiri tetapi Anda harus menambah ukuran buffer.sumber
Jika Anda menggunakan .NET 4, cukup gunakan
File.ReadLines
yang melakukan semuanya untuk Anda. Saya menduga itu banyak sama seperti milik Anda, kecuali itu juga dapat menggunakanFileOptions.SequentialScan
dan buffer yang lebih besar (128 tampaknya sangat kecil).sumber
ReadLines()
adalah malas jadi bekerja dengan baik dengan LINQ.Meskipun
File.ReadAllLines()
merupakan salah satu cara paling sederhana untuk membaca file, itu juga salah satu yang paling lambat.Jika Anda hanya ingin membaca baris dalam file tanpa berbuat banyak, menurut tolok ukur ini , cara tercepat untuk membaca file adalah metode lama:
Namun, jika Anda harus melakukan banyak hal pada setiap baris, maka artikel ini menyimpulkan bahwa cara terbaik adalah yang berikut (dan lebih cepat untuk mengalokasikan sebelumnya string [] jika Anda tahu berapa banyak baris yang akan Anda baca):
sumber
Gunakan kode berikut:
Ini adalah perbedaan BESAR dalam kinerja membaca.
Itu datang pada biaya konsumsi memori, tetapi benar-benar layak!
sumber
File.ReadAllLines
Ada topik yang bagus tentang ini di pertanyaan Stack Overflow Apakah pengembalian hasil lebih lambat dari pengembalian "sekolah lama"? .
Ia mengatakan:
sumber
Jika ukuran file tidak besar, maka lebih cepat membaca seluruh file dan membaginya setelahnya
sumber
File.ReadAllLines()
File.ReadAllLines
memiliki ukuran buffer tetap karena ukuran file diketahui.File.ReadAllLines
membuat daftar dan menambahkan daftar ini dalam satu lingkaran menggunakanStreamReader.ReadLine
(dengan potensi realokasi array yang mendasarinya). Metode ini menggunakan ukuran buffer standar 1024.StreamReader.ReadToEnd
Menghindari bagian parsing garis dan ukuran buffer dapat diatur dalam konstruktor jika diinginkan.Jika Anda memiliki cukup memori, saya telah menemukan beberapa peningkatan kinerja dengan membaca seluruh file ke dalam aliran memori , dan kemudian membuka pembaca aliran untuk membaca baris. Selama Anda benar-benar berencana membaca seluruh file, ini dapat menghasilkan beberapa perbaikan.
sumber
File.ReadAllLines
tampaknya menjadi pilihan yang lebih baik.Anda tidak bisa mendapatkan lebih cepat jika Anda ingin menggunakan API yang ada untuk membaca baris. Tetapi membaca potongan yang lebih besar dan secara manual menemukan setiap baris baru di buffer baca mungkin akan lebih cepat.
sumber