2009-05-11 61 views
11

xem xét chương trình python này:Có thể tăng tốc độ python IO không?

import sys 

lc = 0 
for line in open(sys.argv[1]): 
    lc = lc + 1 

print lc, sys.argv[1] 

Chạy nó trên file văn bản 6GB của tôi, nó hoàn thành trong ~ 2minutes.

Câu hỏi: có thể đi nhanh hơn không?

Lưu ý rằng thời là yêu cầu của:

wc -l myfile.txt 

vậy, tôi nghi ngờ anwer để quesion của tôi chỉ là một đồng bằng "không".

Cũng lưu ý rằng chương trình thật của tôi đang làm một cái gì đó thú vị hơn chỉ đếm dòng, vì vậy xin vui lòng cho một câu trả lời chung chung, không line-đếm-trick (như giữ một siêu dữ liệu đếm dòng trong tập tin)

PS: Tôi đã gắn thẻ "linux" câu hỏi này, bởi vì tôi chỉ quan tâm đến các câu trả lời dành riêng cho Linux. Cảm thấy tự do để cung cấp cho OS-thuyết bất khả tri, hoặc thậm chí khác-OS câu trả lời, nếu bạn có chúng.

Xem thêm follow-up question

+3

có một cái nhìn cho một cuộc thảo luận rất giống nhau ở đây: http://stackoverflow.com/questions/845058/how-to-get-line-count-cheaply-in-python – SilentGhost

+3

Có khả năng phần lớn thời gian đây là chi tiêu chờ đợi trên đĩa. –

+0

Tôi đã trễ bữa tiệc, nhưng đối với các tệp lớn "sed -n '$ =' filename" nhanh hơn "wc -l" – philshem

Trả lời

3

Bạn không thể nhận được bất kỳ nhanh hơn tốc độ đọc đĩa tối đa.

Để đạt tốc độ đĩa tối đa mà bạn có thể sử dụng hai mẹo sau đây:

  1. đọc các tập tin với một bộ đệm lớn. Điều này có thể được mã hóa "bằng tay" hoặc đơn giản bằng cách sử dụng io.BufferedReader (có sẵn trong python2.6 +).
  2. Làm dòng mới đếm trong một chuỗi khác, song song.
+2

-1 không thấy cách thực hiện dòng mới đếm trong chuỗi khác có thể tăng tốc. Nó sẽ làm chậm mọi thứ. Đang chờ chủ đề không khiến bạn đợi nhanh hơn. – nosklo

+4

Thông thường bạn sẽ đúng. Tuy nhiên, trong trường hợp này, việc đọc chuỗi từ tệp sẽ đợi I/O trong khi luồng khác phân tích cú pháp dòng mới. Bằng cách đó - chuỗi trình đọc sẽ không chờ chuỗi phân tích cú pháp phân tích các dòng mới giữa các lần đọc hậu quả. – Barakando

+0

Tôi chấp nhận câu trả lời này mặc dù trong trường hợp cụ thể này, nó không đáng để nỗ lực, vì công việc trên mỗi dòng rất thấp và tôi đã đạt tốc độ tối đa hw. Xem thêm câu hỏi tiếp theo, để biết thêm chi tiết. – Davide

5

đồng bằng "không".

Bạn đã đạt được tốc độ đĩa tối đa.

Ý tôi là, bạn có thể mmap tệp hoặc đọc tệp theo khối nhị phân và sử dụng .count('\n') hoặc thứ gì đó. Nhưng điều đó không có khả năng đưa ra những cải tiến lớn.

4

Nếu bạn cho rằng một đĩa có thể đọc 60MB/s, bạn cần 6000/60 = 100 giây, tức là 1 phút 40 giây. Tôi không nghĩ rằng bạn có thể nhận được bất kỳ nhanh hơn vì đĩa là nút cổ chai.

+1

Số 20 trong tính toán của bạn đến từ đâu? Ý bạn là 6000/60 = 100? 60 không 20, phải không? –

+0

Lần đầu tiên tôi muốn tính nó với 20MB/s, nhưng sau đó tôi nghĩ rằng điều này là quá chậm. –

1

như những người khác đã nói - "không"

Hầu như toàn bộ thời gian của bạn được chi tiêu chờ IO. Nếu đây là thứ bạn cần làm nhiều hơn một lần, bạn có một máy có nhiều ram, bạn có thể giữ tệp trong bộ nhớ. Nếu máy của bạn có 16GB ram, bạn sẽ có 8GB ở/dev/shm để chơi.

Tùy chọn khác: Nếu bạn có nhiều máy, vấn đề này là tầm thường để song song. Tách nó giữa nhiều máy, mỗi máy đếm số dòng mới và thêm kết quả.

1

Lưu ý rằng I/O Python được triển khai trong C, vì vậy không có nhiều may mắn tăng tốc thêm nữa.

+2

Bạn có thể viết mã C hoàn toàn xấu và chậm, do đó nếu nó được viết bằng C không đảm bảo rằng nó sẽ nhanh chóng. Và có thể có chi phí đầu tư (ví dụ: để giải thích bytecode, để đọc theo hàng và lặp lại, v.v.) có thể làm chậm nó xuống. – Davide

12

Ném phần cứng vào sự cố.

Như gs đã chỉ ra, nút cổ chai của bạn là tốc độ truyền đĩa cứng. Vì vậy, không có bạn không thể sử dụng một thuật toán tốt hơn để cải thiện thời gian của bạn, nhưng bạn có thể mua một ổ cứng nhanh hơn.

Chỉnh sửa: Một điểm tốt khác của gs; bạn cũng có thể sử dụng cấu hình RAID để cải thiện tốc độ của mình. Điều này có thể được thực hiện với hardware hoặc phần mềm (ví dụ: OS X, Linux, Windows Server, v.v ...).


quản Equation

(Amount to transfer)/(transfer rate) = (time to transfer)

(6000 MB)/(60 MB/s) = 100 seconds

(6000 MB)/(125 MB/s) = 48 seconds


Giải pháp phần cứng

The ioDrive Duo được cho là giải pháp nhanh nhất cho cài đặt của công ty và "sẽ có sẵn vào tháng 4 năm 2009".

Hoặc bạn có thể kiểm tra ổ cứng WD Velociraptor (10.000 vòng/phút).

Ngoài ra, tôi nghe thấy Seagate Cheetah là một tùy chọn tốt (15.000 vòng/phút với tốc độ truyền 125MB/s duy trì).

+3

RAID có thể nhanh hơn nhiều. –

7

Bí quyết không làm cho các electron di chuyển nhanh hơn (điều đó khó làm) nhưng để có được nhiều công việc hơn cho mỗi đơn vị thời gian.

Trước tiên, hãy chắc chắn đọc tệp 6 GB của bạn là I/O bị ràng buộc, không phải CPU bị ràng buộc.

Nếu I/O bị ràng buộc, hãy xem xét mẫu thiết kế "Fan-Out".

  • Quy trình gốc sinh ra một nhóm trẻ em.

  • Cha mẹ đọc tệp 6Gb và giao dịch hàng cho trẻ bằng cách ghi vào đường ống STDIN của chúng. Thời gian đọc 6 GB sẽ không thay đổi. Việc xử lý hàng nên liên quan đến việc xử lý cha mẹ ít nhất có thể. Bộ lọc hoặc số lượng rất đơn giản nên được sử dụng.

    Đường ống là kênh trong bộ nhớ để liên lạc. Đó là một bộ đệm được chia sẻ với một người đọc và một nhà văn.

  • Mỗi đứa trẻ đọc một hàng từ STDIN và thực hiện công việc phù hợp. Mỗi đứa trẻ có lẽ nên viết một tệp đĩa đơn giản với kết quả cuối cùng (tóm tắt, giảm). Sau đó, kết quả trong các tệp đó có thể được hợp nhất.

+0

có thể (trên viên đạn thứ ba) bạn có nghĩa là tất cả trẻ em nên nói chuyện với nhau trong bộ nhớ, vì đĩa đã rất bận rộn – Davide

+0

Ống * là * các kênh truyền thông trong bộ nhớ. –

+0

Có, nhưng trong viên đạn thứ ba của bạn, bạn viết: "Mỗi đứa trẻ có lẽ nên viết một tệp đĩa đơn giản." – Davide

1

2 phút có vẻ thích hợp để đọc toàn bộ tệp 6gb. Không thực sự nhiều bạn có thể làm cho các thuật toán hoặc hệ điều hành để tăng tốc độ lên.Tôi nghĩ bạn có hai tùy chọn:

  1. Ném tiền vào vấn đề và nhận phần cứng tốt hơn. Có lẽ là lựa chọn tốt nhất nếu dự án này là dành cho công việc của bạn.

  2. Không đọc toàn bộ tệp. Tôi không biết những gì bạn đang cố gắng để làm với các dữ liệu, vì vậy có thể bạn không có bất kỳ tùy chọn, nhưng để đọc toàn bộ điều. Mặt khác, nếu bạn đang quét toàn bộ tệp cho một điều cụ thể, thì có thể đặt một số siêu dữ liệu trong đó vào lúc bắt đầu sẽ hữu ích.

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