Có vẻ như mã của bạn là I/O bị ràng buộc. Điều này có nghĩa là đa xử lý sẽ không giúp ích gì - nếu bạn dành 90% thời gian đọc từ đĩa, có thêm 7 quy trình đang chờ đọc tiếp theo sẽ không giúp gì cả.
Và, trong khi sử dụng mô-đun đọc CSV (cho dù số csv
hoặc thứ gì đó như NumPy hoặc Pandas) có thể là một ý tưởng hay để đơn giản, nó không tạo ra sự khác biệt nhiều về hiệu suất.
Tuy nhiên, bạn nên kiểm tra xem bạn thực sự là bị ràng buộc I/O, thay vì chỉ đoán. Chạy chương trình của bạn và xem liệu mức sử dụng CPU của bạn có gần 0% hay gần 100% hay một lõi. Làm những gì Amadan đề xuất trong một bình luận, và chạy chương trình của bạn chỉ với pass
để xử lý và xem liệu nó cắt giảm 5% thời gian hay 70%. Thậm chí bạn có thể thử so sánh với một vòng lặp qua os.open
và os.read(1024*1024)
hoặc thứ gì đó và xem liệu có nhanh hơn không.
Kể từ khi bạn sử dụng Python 2.x, Python dựa vào thư viện stdio C để đoán số lượng bộ đệm cùng một lúc, do đó có thể buộc phải đệm nhiều hơn. Cách đơn giản nhất để làm điều đó là sử dụng readlines(bufsize)
cho một số lớn bufsize
. (Bạn có thể thử các con số khác nhau và đo chúng để xem điểm cao nhất là ở đâu. Theo kinh nghiệm của tôi, thường là bất cứ thứ gì từ 64K-8MB đều giống nhau, nhưng tùy thuộc vào hệ thống của bạn có thể khác - đặc biệt nếu bạn đang đọc ra một hệ thống tập tin mạng với thông lượng lớn nhưng độ trễ kinh khủng rằng đầm lầy thông-vs-độ trễ của ổ đĩa vật lý thực tế và bộ nhớ đệm hệ điều hành nào)
vì vậy, ví dụ:.
bufsize = 65536
with open(path) as infile:
while True:
lines = infile.readlines(bufsize)
if not lines:
break
for line in lines:
process(line)
Trong khi đó, giả sử bạn đang sử dụng hệ thống 64 bit, bạn có thể thử sử dụng mmap
thay vì đọc tệp ở vị trí đầu tiên. Điều này chắc chắn không phải là được bảo đảm để tốt hơn, nhưng nó có thể trở nên tốt hơn, tùy thuộc vào hệ thống của bạn.Ví dụ:
with open(path) as infile:
m = mmap.mmap(infile, 0, access=mmap.ACCESS_READ)
Một Python mmap
là sắp xếp của một lạ đối tượng nó hoạt động như một str
và giống như một file
cùng một lúc, vì vậy bạn có thể, ví dụ, tay quét lặp cho dòng mới, hoặc bạn có thể gọi readline
trên đó như thể nó là một tập tin. Cả hai đều sẽ xử lý nhiều hơn từ Python so với việc lặp lại tập tin dưới dạng dòng hoặc thực hiện hàng loạt readlines
(bởi vì một vòng lặp trong C bây giờ là bằng Python thuần túy… mặc dù có thể bạn có thể thực hiện điều đó với re
hoặc bằng phần mở rộng Cython đơn giản ?)… Nhưng lợi thế I/O của hệ điều hành biết việc bạn đang làm với ánh xạ có thể làm giảm nhược điểm của CPU.
Thật không may, Python không hiển thị cuộc gọi madvise
mà bạn sử dụng để tinh chỉnh mọi thứ nhằm cố gắng tối ưu hóa điều này trong C (ví dụ: thiết lập rõ ràng MADV_SEQUENTIAL
thay vì đoán hạt nhân hoặc buộc trang lớn trong suốt) - nhưng bạn thực sự có thể ctypes
chức năng ra khỏi libc
.
đa xử lý; đọc lặp đi lặp lại chunked. Tại 3GB cho mỗi tập tin bạn ** KHÔNG ** muốn được đọc hoàn toàn vào bộ nhớ; bạn có thể thổi tài nguyên bộ nhớ của bạn. –
Có vẻ như một cơ sở dữ liệu sẽ giúp bạn tùy thuộc vào loại xử lý mà bạn đang thực hiện. – squiguy
Không nếu đây là nhiệm vụ đơn lẻ; Dữ liệu trong; Chế biến; dữ liệu ra; xóa dữ liệu nguồn. –