2010-07-08 36 views
7

Tôi có một số lượng lớn (> 100k) tệp tương đối nhỏ (1kb - 300kb) mà tôi cần đọc và xử lý. Tôi hiện đang lặp qua tất cả các tệp và sử dụng File.ReadAllText để đọc nội dung, xử lý và sau đó đọc tệp tiếp theo. Điều này là khá chậm và tôi đã tự hỏi nếu có một cách tốt để tối ưu hóa nó.Đọc một số lượng lớn tệp nhanh chóng

Tôi đã thử sử dụng nhiều chuỗi nhưng vì điều này có vẻ là IO bị ràng buộc, tôi không thấy bất kỳ cải tiến nào.

+0

Phần nào mất nhiều thời gian nhất? Đang tải các tệp hoặc xử lý chúng? –

+0

@NickLarsen: Đang tải tệp. – Tim

+0

Ngay cả khi tải chúng mất nhiều thời gian nhất, đa luồng vẫn có thể cung cấp cho bạn mức tăng, vì nó có thể ít nhất loại bỏ hầu hết các khía cạnh xử lý khỏi tổng thời gian chạy. –

Trả lời

7

Bạn có nhiều khả năng đúng - Đọc rằng nhiều tệp có thể sẽ giới hạn khả năng tăng tốc tiềm năng của bạn vì Đĩa I/O sẽ là yếu tố giới hạn.

Điều đó đang được nói, bạn rất có thể có thể thực hiện một cải tiến nhỏ bằng cách chuyển quá trình xử lý dữ liệu thành một chuỗi riêng biệt.

Tôi khuyên bạn nên cố gắng tạo một chuỗi "nhà sản xuất" duy nhất đọc tệp của bạn. Chủ đề này sẽ bị giới hạn IO. Khi nó đọc một tập tin, nó có thể đẩy "xử lý" vào một ThreadPool thread (.NET 4 nhiệm vụ làm việc tuyệt vời cho điều này quá) để làm việc xử lý, mà sẽ cho phép nó ngay lập tức đọc các tập tin tiếp theo.

Điều này ít nhất sẽ mất "thời gian xử lý" trong tổng thời gian chạy, làm cho tổng thời gian cho công việc của bạn gần bằng với IO đĩa, miễn là bạn có thêm một hoặc hai lõi để làm việc với ..

+0

lol Đúng như tôi đã nói. Tư tưởng lớn gặp nhau – Icemanind

2

Điều tôi sẽ làm là xử lý trong một chuỗi riêng biệt. Tôi sẽ đọc trong một tập tin và lưu trữ dữ liệu trong hàng đợi, sau đó đọc trong tập tin tiếp theo và vv.

Trong chuỗi thứ hai của bạn, hãy để luồng đọc dữ liệu từ hàng đợi đó và xử lý nó. Xem nếu điều đó giúp!

0

Đây có thể là thời gian tìm kiếm đĩa là yếu tố hạn chế (đây là một trong những nút cổ chai phổ biến nhất khi thực hiện Make, thường bao gồm nhiều tệp nhỏ). Thiết kế hệ thống tập tin câm có một mục nhập thư mục và nhấn mạnh vào một con trỏ đến các khối đĩa cho một tập tin, và rằng người bảo đảm tối thiểu là 1 tìm kiếm cho mỗi tập tin.

Nếu bạn đang sử dụng Windows, tôi sẽ chuyển sang sử dụng NTFS (lưu trữ các tệp nhỏ trong mục mục nhập thư mục (-> lưu một đĩa tìm kiếm trên mỗi tệp). nhưng CPU có giá rẻ và nhanh nhưng không gian đĩa ít hơn -> ít thời gian đọc hơn), điều này có thể không liên quan nếu tệp của bạn nhỏ, có thể có một hệ thống tệp Linux tương đương, nếu đó là vị trí của bạn.

Yes , bạn nên khởi chạy một loạt chủ đề để đọc các tệp:

 forall filename in list: fork(open filename, process file, close filename) 

Bạn có thể phải điều tiết để ngăn chặn ru nning ra khỏi chủ đề, nhưng tôi muốn bắn cho hàng trăm không 2 hoặc 3. Nếu bạn làm điều đó, bạn đang nói với hệ điều hành rằng nó có thể đọc rất nhiều nơi trên đĩa, và nó có thể đặt nhiều yêu cầu bằng cách đặt vị trí đĩa (elevator algorithm), và điều đó cũng sẽ giúp giảm thiểu chuyển động đầu.

0

Tôi muốn giới thiệu "MultiThreading" để giải quyết vấn đề này. Khi tôi đọc câu trả lời của bạn, đột nhiên thấy rằng câu trả lời của Reed Copsey sẽ rất hiệu quả. Bạn có thể tìm thấy mẫu cho giải pháp này được chuẩn bị bởi Elmue trên số link này. Tôi hy vọng điều này có thể hữu ích và nhờ vào số Reed Copsey. Kính trọng

0

Tôi đồng ý với ý kiến ​​của Reed và Icemanind. Ngoài ra, hãy xem xét làm thế nào để tăng IO đĩa.Ví dụ, phân tán các tập tin trên nhiều đĩa để chúng có thể được đọc song song và sử dụng các đĩa nhanh hơn như SSD hoặc có thể là một đĩa RAM.

Các vấn đề liên quan