2010-06-10 29 views
5

Tôi phải thực hiện thao tác liên kết I/o nặng, ví dụ: Phân tích các tệp lớn và chuyển đổi từ một định dạng sang định dạng khác. Ban đầu tôi sử dụng để làm điều đó một cách serially, tức là phân tích cú pháp cái khác ..! Hiệu suất rất kém (nó được sử dụng mất 90 + giây). Vì vậy, tôi quyết định sử dụng luồng để cải thiện hiệu suất. Tôi đã tạo một chuỗi cho mỗi tệp. (4 chủ đề)luồng và hiệu suất của Python?

for file in file_list: 
      t=threading.Thread(target = self.convertfile,args = file) 
      t.start() 
      ts.append(t) 
for t in ts: 
      t.join() 

Nhưng thật ngạc nhiên, không có cải thiện hiệu suất nào. Bây giờ cũng phải mất khoảng 90 giây để hoàn thành nhiệm vụ. Vì đây là hoạt động liên kết I/o, tôi đã dự kiến ​​sẽ cải thiện hiệu suất.

Trả lời

10

Theo trình thông dịch Python thông thường, luồng sẽ không phân bổ nhiều lõi CPU cho chương trình của bạn vì global interpreter lock (aka. GIL).

Mô-đun multiprocessing có thể giúp bạn ở đây. (Lưu ý rằng nó đã được giới thiệu trong Python 2.6, nhưng backports tồn tại cho Python 2.5.)

Như MSalters nói, nếu chương trình của bạn là I/O bị ràng buộc, điều này có ích hay không. Nhưng nó có thể là giá trị một shot :)

Để đạt được những gì bạn muốn sử dụng mô-đun này:

import multiprocessing 

MAX_PARALLEL_TASKS = 8 # I have an Intel Core i7 :) 

pool = multiprocessing.Pool(MAX_PARALLEL_TASKS) 

pool.map_async(convertfile, filelist) 

pool.close() 
pool.join() 

quan trọng! Chức năng mà bạn chuyển đến map_async phải được chọn. Nói chung, các phương pháp thể hiện KHÔNG được chọn trừ khi bạn kỹ thuật chúng thành như vậy! Lưu ý rằng convertfile ở trên là một chức năng.

Nếu bạn thực sự cần lấy lại kết quả từ convertfile, cũng có nhiều cách để thực hiện điều đó. Các ví dụ trên trang tài liệu đa xử lý phải làm rõ.

+0

Cảm ơn delty..Nhưng mô-đun đa xử lý có vấn đề riêng của mình. 1) Tôi phải cấu trúc lại mã của mình vì tôi không thể sử dụng các phương thức ví dụ. 2) Tôi có một phương thức thể hiện có nhiều trình xử lý tập tin .. Trình xử lý tệp được đóng trong các tiến trình con không được chấp nhận. Vì vậy, tôi cần phải mở chúng một lần nữa. Thật không may tôi không có cách nào để biết chúng vì chúng được truyền trong quá trình instantiation – kumar

+0

Nó không phải là chức năng chuyển đổi chính nó được thực hiện trong một quá trình riêng biệt. Có cách nào bạn có thể làm một phần instantiation trong các quá trình riêng biệt? Ví dụ. viết một hàm hoặc thậm chí là một tập lệnh riêng biệt để thực hiện một sự khởi tạo và chuyển đổi đơn lẻ; sau đó viết "tập lệnh chính" sử dụng mô-đun đa xử lý để chạy các chức năng này. Có thể chạy các tập lệnh riêng biệt bằng mô-đun [subprocess] (http://docs.python.org/library/subprocess.html). Nếu có rất nhiều dữ liệu được chia sẻ, thì có, đó là nơi đa xử lý trở nên phức tạp. Nhưng có nhiều công cụ hơn trong mô-đun đó :) – detly

2

Luồng cho phép hệ điều hành phân bổ nhiều lõi CPU hơn cho chương trình của bạn. Nếu đó là I/O bị ràng buộc, điều đó có nghĩa là tốc độ bị giới hạn bởi tốc độ hệ thống tốc độ I/O thay vì tốc độ CPU. Trong những trường hợp đó, việc phân bổ nhiều lõi CPU không nhất thiết phải trợ giúp - bạn vẫn đang chờ đợi trên hệ thống con I/O.

+0

Nhưng tôi tin rằng chuyển đổi chuỗi sẽ xảy ra khi một luồng đang đợi I/O subsyetm, phải không? Vì vậy, tôi đang làm những điều song song bây giờ có nghĩa là tôi có thể mong đợi một số cải tiến hiệu suất ?? – kumar

+5

Luồng trong Python không phân bổ nhiều lõi CPU cho chương trình. – detly

+0

@kumar: Khi câu trả lời cho biết, nếu bạn đang I/O bị ràng buộc - I/O của bạn sẽ khó thực hiện - nhiều thời gian CPU hơn hoặc xử lý song song sẽ không làm cho I/O kết thúc sớm hơn. – Josh