Để tìm cách nhanh nhất để đọc từng dòng tệp, bạn sẽ phải thực hiện một số điểm chuẩn. Tôi đã thực hiện một số thử nghiệm nhỏ trên máy tính của mình nhưng bạn không thể ngờ rằng kết quả của tôi áp dụng cho môi trường của bạn.
Sử dụng StreamReader.ReadLine
Đây là cơ bản phương pháp của bạn. Vì một số lý do, bạn đặt kích thước bộ đệm thành giá trị nhỏ nhất có thể (128). Tăng điều này sẽ nói chung tăng hiệu suất. Kích thước mặc định là 1.024 và các lựa chọn tốt khác là 512 (kích thước cung trong Windows) hoặc 4.096 (kích thước cụm trong NTFS). Bạn sẽ phải chạy một điểm chuẩn để xác định kích thước bộ đệm tối ưu. Một bộ đệm lớn hơn - nếu không nhanh hơn - ít nhất là không chậm hơn một bộ đệm nhỏ hơn.
const Int32 BufferSize = 128;
using (var fileStream = File.OpenRead(fileName))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) {
String line;
while ((line = streamReader.ReadLine()) != null)
// Process line
}
Hàm FileStream
tạo cho phép bạn chỉ định FileOptions . Ví dụ: nếu bạn đang đọc một tệp lớn liên tục từ đầu đến cuối, bạn có thể được hưởng lợi từ FileOptions.SequentialScan
. Một lần nữa, điểm chuẩn là điều tốt nhất bạn có thể làm.
Sử dụng File.ReadLines
Điều này rất giống với giải pháp của riêng bạn ngoại trừ việc nó được thực hiện bằng cách sử dụng StreamReader
kích thước bộ đệm cố định là 1.024. Trên máy tính của tôi, kết quả này có hiệu suất tốt hơn một chút so với mã của bạn với kích thước bộ đệm là 128. Tuy nhiên, bạn có thể tăng hiệu suất tương tự bằng cách sử dụng kích thước bộ đệm lớn hơn. Phương pháp này được thực hiện bằng cách sử dụng khối lặp và không tiêu thụ bộ nhớ cho tất cả các dòng.
var lines = File.ReadLines(fileName);
foreach (var line in lines)
// Process line
Sử dụng File.Read ALLLines
Điều này rất giống với phương thức trước ngoại trừ phương thức này phát triển một danh sách các chuỗi được sử dụng để tạo mảng các dòng được trả về để yêu cầu bộ nhớ cao hơn. Tuy nhiên, nó trả về String[]
và không IEnumerable<String>
cho phép bạn truy cập ngẫu nhiên các dòng.
var lines = File.ReadAllLines(fileName);
for (var i = 0; i < lines.Length; i += 1) {
var line = lines[i];
// Process line
}
Sử dụng String.Split
Phương pháp này chậm hơn đáng kể, ít nhất là trên các tệp lớn (được thử nghiệm trên tệp 511 KB), có thể do cách String.Split
triển khai. Nó cũng phân bổ một mảng cho tất cả các dòng tăng bộ nhớ cần thiết so với giải pháp của bạn.
using (var streamReader = File.OpenText(fileName)) {
var lines = streamReader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
// Process line
}
Đề nghị của tôi là sử dụng File.ReadLines
vì nó sạch sẽ và hiệu quả. Nếu bạn yêu cầu các tùy chọn chia sẻ đặc biệt (ví dụ: bạn sử dụng FileShare.ReadWrite
), bạn có thể sử dụng mã của riêng mình nhưng bạn nên tăng kích thước bộ đệm.
Fastest
bạn là từ quan điểm hiệu suất hay phát triển?