Vì Python được phát triển lần đầu tiên cách đây 29 năm nên không có gì ngạc nhiên khi nó được thiết kế như một ngôn ngữ lập trình tuyến tính khi CPU lõi đơn vẫn đang thống trị thị trường. Trên thực tế, nhà phát triển CPython có thể vẫn cảm thấy nóng khi nói đến đồng thời. May mắn thay, chúng tôi, những người mới học Python có thể nghỉ ngơi và tận hưởng thành quả của PEP 371, nơi mà
n = 1006 đã chính thức được thêm vào các thư viện tiêu chuẩn vào năm 2008 và PEP 3156, nơi mà
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 1007 đã được đưa vào các thư viện tiêu chuẩn vào năm 2012. Trong phần đầu tiên của loạt bài về xử lý song song với Python, chúng ta sẽ xem xét đa luồng, cách triển khai nó với
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 1006Đa luồng so với Đa xử lý
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
TL; DR. Song song hóa tác vụ liên kết với CPU với đa xử lý và tác vụ liên kết với I/O với đa luồng
Nguồn. Wikimedia Commons
Chủ đề là một luồng thực thi riêng biệt. Khi bạn có một nhóm worker thread, chúng sẽ thực thi gần như đồng thời. Các luồng này sẽ chia sẻ một không gian dữ liệu chung, do đó, khái niệm Khóa thông dịch viên toàn cầu [GIL] rất quan trọng khi bạn cố gắng đa luồng tập lệnh python của mình. Những gì GIL làm là, trong ngắn hạn, một luồng Python chạy tại một thời điểm để tránh những thay đổi không nhất quán trong bộ nhớ dùng chung hoặc về lâu dài là tạo môi trường quản lý bộ nhớ an toàn cho luồng để đưa các thư viện C không an toàn cho luồng vào Python . Như vậy, các luồng sẽ khóa luồng gọi khi chúng cần sử dụng CPU để tính toán. Điều này làm cho các luồng kém hiệu quả hơn đối với các tác vụ liên quan đến CPU và hơn thế nữa đối với các tác vụ liên quan đến I/O, ví dụ:. g. kết nối mạng, phát hành các hoạt động cơ sở dữ liệu, v.v.
Quy trình có thể được hiểu là một quy trình Python riêng biệt đã được rẽ nhánh từ quy trình mẹ và có trình thông dịch Python riêng. Do đó, mỗi quy trình sẽ có GIL riêng và sẽ không khóa các quy trình khác khi thực thi trên lõi CPU. Giá để tránh tắc nghẽn GIL là có chi phí bộ nhớ lớn hơn dưới dạng bản sao của không gian địa chỉ hoặc sao chép khi ghi nếu cần hỗ trợ cho mọi quy trình. Do đó, các quy trình thường được ưu tiên hơn khi thực hiện các tác vụ liên quan đến CPU e. g. thao tác ma trận
Triển khai đa luồng của PythonThư viện tiêu chuẩn của Python,
n = 1006 có giao diện cho luồng có sẵn qua
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 30. Đối với các cựu chiến binh Python dày dạn kinh nghiệm,
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 31 là thư viện ban đầu cho việc này. Giao diện này cung cấp các chức năng sau, nhưng mỗi phương thức có những hạn chế khác nhau về cách truyền đối số và không dễ dàng để chúng tôi theo dõi tiến trình
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
- apply[func[, args[, kwds]]] [Điều này được triển khai dưới dạng
%%timeit -n 3
2]
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] - apply_async[func[, args[, kwds[, callback[, error_callback]]]]]
- map[func, iterable[, chunksize]] [Điều này được triển khai dưới dạng
%%timeit -n 3
3]
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] - map_async[func, iterable[, chunksize[, callback[, error_callback]]]]
- imap[func, iterable[, chunksize]]
- imap_unordered[func, iterable[, chunksize]]
- starmap[func, iterable[, chunksize]] [Điều này được triển khai dưới dạng
%%timeit -n 3
4]
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] - starmap_async[func, iterable[, chunksize[, callback[, error_callback]]]]
Trước khi chúng ta đi sâu vào các phương pháp này, hãy thảo luận về ưu và nhược điểm, trước tiên hãy thiết lập bối cảnh
Khi chạy nó với
%%timeit -n 35 ta được kết quả như sau
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 1000
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Giả sử chúng ta muốn, vì lý do nào đó, chạy nó hàng trăm lần
n = 100ÁP DỤNG & ÁP DỤNG_ASYNC
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Truyền một chức năng cho nhóm chủ đề. Điều này có hai biến thể.
%%timeit -n 36 và
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 37. Khi sử dụng phương thức
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 38, bạn sẽ cần truyền một hàm có thể gọi được, cùng với một số đối số và/hoặc kwargs tùy chọn. Khi thực thi chức năng, nó sẽ chặn luồng gọi cho đến khi kết quả sẵn sàng hoặc một ngoại lệ đã được đưa ra. Do đó,
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 39 thường được ưu tiên
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Khi sử dụng
%%timeit -n 39, thay vì kết quả thực tế, nó sẽ trả về
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10071, về cơ bản là lời hứa về kết quả mà bạn có thể nhận được bằng cách sử dụng hàm
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10072. bạn cũng có thể chuyển vào một hàm
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10073 và một hàm
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10074 sẽ được thực thi khi luồng hoàn thành công việc và khi nó bị lỗi như nó luôn có trong mã của tôi
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
ưu
- lần lượt chuyển các chức năng đến nhóm công nhân cho phép linh hoạt hơn trong việc lập lịch trình
- biến thể duy nhất trong triển khai của Python hỗ trợ cả args và kwargs
Nhược điểm
- gán các chức năng từng cái một để tăng chi phí mạng dưới dạng liên lạc giữa các luồng
- áp dụng sẽ chặn chuỗi người gọi và có thể dễ dàng chậm hơn điểm chuẩn
- tùy thuộc vào chức năng cụ thể, việc sử dụng
n = 100
75 có thể có thông lượng kém hơn do tải trọng không thể được chuyển theo lô
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
ÁP DỤNG
%%timeit -n 3
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
ÁP DỤNG + TQDM
n = 1007
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
ÁP DỤNG_ASYNC
n = 1004
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
ÁP DỤNG_ASYNC + TQDM
n = 1005
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
APPLY_ASYNC + TQDM trong Gọi lại
n = 1006MAP & MAP_ASYNC
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Tranh luận
- chức năng. Có thể gọi cho từng luồng riêng lẻ để thực thi
- lặp đi lặp lại. Một iterable của arg sẽ được chuyển đến hàm
- cỡ khối. Một số nguyên dương tùy chọn [mặc định là 1] chỉ định kích thước [xấp xỉ] của các khối, các tác vụ được đặt tên, có thể lặp lại sẽ được cắt nhỏ thành. Các tác vụ này và sẽ được gán cho các luồng để thực thi luồng được xác định trong func
- gọi lại. [Chỉ dành cho map_async] Có thể gọi tùy chọn [mặc định là
n = 100
76] sẽ được gọi mỗi khi có kết quả
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] - error_callback. [Chỉ dành cho map_async] Một tùy chọn có thể gọi được [mặc định là
n = 100
76] sẽ được gọi mọi lúc khi một ngoại lệ chưa được phát hiện được đưa ra trong func
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
trả lại
- Danh sách kết quả
ưu
- Không cần lặp qua danh sách dữ liệu vì điều này sẽ được xử lý trực tiếp bởi
n = 100
78 hoặc
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
79
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] n = 100
40 cho phép thông lượng tốt hơn
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]- Trật tự được bảo toàn, tôi. e. thứ tự thực hiện giống như thứ tự xuất
Một nhược điểm lớn đối với
n = 10041 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10075 là chúng ta sẽ cần thực thi lặp đi lặp lại
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10043 hoặc biến thể không đồng bộ cho mỗi tập hợp đối số và/hoặc kwargs. Lặp lại không được tối ưu hóa hầu như luôn là cơn ác mộng khi nói đến khả năng mở rộng. Trong trường hợp này,
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10044 là dreamcatcher của chúng ta. Tất cả những gì chúng ta cần làm là chuyển vào iterable và viola
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Cũng giống như
n = 10041,
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10078 có một biến thể không đồng bộ thường hoạt động tốt hơn vì
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10078 sẽ chặn luồng gọi cho đến khi trả về kết quả
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Một đối số rất hữu ích khác là
n = 10040, chấp nhận một số tự nhiên với giá trị mặc định là 1. Iterable của chúng ta sẽ được chia thành các phần, được gọi là tác vụ, có độ dài gần bằng độ dài của chunksize. Mỗi chuỗi sẽ là một nhiệm vụ mà họ cần phải hoàn thành trước khi yêu cầu một nhiệm vụ mới. Về bản chất, ________ 249 giúp bạn linh hoạt hơn trong việc lên lịch cho từng tác vụ, trong khi việc có ________ 250 mang lại cho bạn [nói chung] thông lượng tốt hơn và giảm số lần liên lạc giữa các luồng. Một nguyên tắc chung là có
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10051 nếu bạn không biết mỗi nhiệm vụ sẽ mất bao lâu để hoàn thành [e. g. tối ưu hóa], và có
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10052 nếu bạn đang mong đợi các tác vụ hoàn thành trong cùng một khoảng thời gian
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Nhược điểm
n = 100
78 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
79 sẽ chuyển đổi đối số
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
55 thành một danh sách trước khi thực hiện, gây thêm chi phí bộ nhớ
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
78 sẽ chặn các chủ đề gọi cho đến khi kết quả được trả về
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
78 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
79 chỉ cho phép truyền một đối số vào hàm, nghĩa là các đối số khác [từ đối số thứ hai trở đi] phải có giá trị được xác định trước hoặc giá trị mặc định
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]- Hãy cẩn thận với việc sử dụng bộ nhớ, đặc biệt là khi thời gian lặp lại lâu hơn
n = 10078 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10079 cũng có một số nhược điểm. Một điều đặc biệt khó chịu là nó chỉ cho phép một đối số. Nếu chức năng của bạn chấp nhận nhiều đối số hoặc kwarg, đây là ba cách [nói chung] để đi bộ xung quanh nó
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
1. Chỉ cần làm cho nó xảy ra
Không được khuyến khích;
Bạn sẽ cần chỉ định mọi đối số ngay cả khi chúng là tùy chọn và cũng có thể cần phải bọc chức năng mục tiêu của bạn để biến điều đó thành hiện thực
2. Phương pháp một phần
Chỉ khi đối số thay đổi là đối số đầu tiên được hàm chấp nhận
3. Không sử dụng
n = 10061 hoặc
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10062
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Vâng, có những lựa chọn thay thế tốt hơn, như
n = 10063
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
BẢN ĐỒ
%%timeit -n 35
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
BẢN ĐỒ + TQDM
%%timeit -n 36
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
MAP_ASYNC
%%timeit -n 37IMAP & IMAP_UNORDERED
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Tranh luận
- chức năng. Có thể gọi cho từng luồng riêng lẻ để thực thi
- lặp đi lặp lại. Một iterable của arg sẽ được chuyển đến hàm
- cỡ khối. Một số nguyên dương tùy chọn [mặc định là 1] chỉ định kích thước [xấp xỉ] của các khối, các tác vụ được đặt tên, có thể lặp lại sẽ được cắt nhỏ thành. Các tác vụ này và sẽ được gán cho các luồng để thực thi luồng được xác định trong func
trả lại
- Trình tạo kết quả
ưu
- Không cần lặp qua danh sách dữ liệu vì điều này sẽ được xử lý trực tiếp bởi
n = 100
78 hoặc
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
79
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] n = 100
40 cho phép thông lượng tốt hơn
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]- Đối số
n = 100
55 sẽ không được chuyển đổi thành
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
68 trước khi chuyển đến các luồng, tránh tràn ngăn xếp khi
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
55 là một lần lặp dài, không thuộc danh sách
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] - Kết quả sẽ được lưu giữ dưới dạng trình tạo thay vì được chuyển đổi thành
n = 100
68 trước khi quay lại
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] %%timeit -n 3
51 sẽ trả về kết quả ngay sau khi hoàn thành mà không đảm bảo duy trì trật tự trong lần lặp đầu vào
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 352 được định nghĩa chính thức là phiên bản lười biếng hơn của
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10078, có nghĩa là nó sẽ chuyển đầu vào có thể lặp lại của bạn thành một
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10068 trước khi cắt nó thành các tác vụ, cũng như không đưa kết quả vào danh sách trước khi quay lại. Thay vào đó, nó sử dụng
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 355 và
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 356 để ủy thác nhiệm vụ. Không giống như
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10078 sẽ trả về một danh sách kết quả hoặc
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10079 trả về lời hứa về kết quả,
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 352 và
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 351 trả về kết quả ngay khi worker thread đưa ra kết quả. Do sự khác biệt này, kết quả không thể được đưa vào danh sách và thay vào đó sẽ cần nằm trong trình tạo, nơi người dùng có thể sử dụng
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 361 để tìm nạp kết quả mới nhất. Điều này sẽ đặc biệt nếu chương trình của bạn không cần đợi tất cả các kết quả để bắt đầu bất kỳ xử lý hậu kỳ nào. Trên hết, nếu thứ tự thực hiện không quan trọng đối với bạn, thì về mặt lý thuyết,
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 351 sẽ tốt hơn vì nó sẽ mang lại kết quả ngay sau khi thực thi được thực hiện bất kể thứ tự lặp lại của đầu vào [i. e. nếu bạn vượt qua
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 363, bạn có thể nhận được kết quả là
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 364, với thứ tự kết quả hoàn toàn được xác định bởi thời gian chạy]
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Cũng giống như
n = 10078 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10079,
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 352 và biến thể của nó cũng có
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10040, chấp nhận một số tự nhiên với giá trị mặc định là 1. Một nguyên tắc chung là có
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10051 nếu bạn không biết mỗi nhiệm vụ sẽ mất bao lâu để hoàn thành [e. g. tối ưu hóa], và có
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10052 nếu bạn đang mong đợi các tác vụ hoàn thành trong cùng một khoảng thời gian
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Nhược điểm
- Bạn có thể đang làm việc với tập hợp kết quả chưa hoàn chỉnh khi tương tác với trình tạo
- Tất cả sự tiện lợi của danh sách sẽ không có sẵn khi xử lý kết quả
%%timeit -n 3
52 và
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]%%timeit -n 3
51 chỉ cho phép truyền một đối số vào hàm, nghĩa là các đối số khác [từ đối số thứ hai trở đi] phải có giá trị được xác định trước hoặc giá trị mặc định
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]%%timeit -n 3
51 sẽ trả về kết quả ngay sau khi hoàn thành mà không đảm bảo duy trì trật tự trong lần lặp đầu vào
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]- Hãy cẩn thận với việc sử dụng bộ nhớ, đặc biệt là khi thời gian lặp lại lâu hơn
Tóm lại, không sử dụng
%%timeit -n 374 và
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 375 nếu bạn không thoải mái với trình tạo hoặc nếu bạn cần hoàn thành kết quả trước khi tiếp tục và không sử dụng
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
%%timeit -n 375 nếu thứ tự quan trọng đối với bạn. Nếu bạn muốn chuyển trình tạo trở lại danh sách, hãy sử dụng
with Pool[processes=n_job] as pool:
results = list[pool.apply[func, args=[i]] for i in data]>>> 11.1 s ± 901 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10078 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10079 để thay thế
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Để giải quyết hạn chế của một đối số, vui lòng tham khảo
n = 10078 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10079
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
IMAP
n = 1000
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
IMAP + TQDM
n = 1001
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
IMAP_UNORDERED
n = 1002
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
IMAP_UNORDERED + TQDM
n = 1003SƠ ĐỒ STAR & STARMAP_ASYNC
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Tranh luận
- chức năng. Có thể gọi cho từng luồng riêng lẻ để thực thi
- lặp đi lặp lại. Một iterable của iterable của arg[S] sẽ được chuyển đến và giải nén bởi hàm
- cỡ khối. Một số nguyên dương tùy chọn [mặc định là 1] chỉ định kích thước [xấp xỉ] của các khối, các tác vụ được đặt tên, có thể lặp lại sẽ được cắt nhỏ thành. Các tác vụ này và sẽ được gán cho các luồng để thực thi luồng được xác định trong func
- gọi lại. [Chỉ dành cho starmap_async] Có thể gọi tùy chọn [mặc định là
n = 100
76] sẽ được gọi mỗi khi có kết quả
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] - error_callback. [Chỉ dành cho starmap_async] Có thể gọi tùy chọn [mặc định là
n = 100
76] sẽ được gọi mọi lúc khi một ngoại lệ chưa được phát hiện được đưa ra trong func
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
trả lại
- Danh sách kết quả
ưu
- Nhiều đối số có thể được chuyển đến
n = 100
03
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each] n = 100
40 cho phép thông lượng tốt hơn
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]- Trật tự được bảo toàn, tôi. e. thứ tự thực hiện giống như thứ tự xuất
n = 10063 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10006 đã được giới thiệu trong Python 3. 3 để giải quyết chính xác vấn đề trong đó nhiều đối số không thể dễ dàng chuyển đến hàm đích. Thay vì truyền vào một iterable của arg, chúng ta sẽ cần truyền vào một iterable của iterable của args i. e. nếu chúng ta chuyển
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10007 vào hàm
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10008, nó sẽ thực thi
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10009 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10010. Vì vậy, hãy nhớ bọc các đối số của bạn thành một bộ [bộ nhớ không phát triển trên cây] ngay cả khi nó chỉ có một đối số [chúng tôi không phán xét]. Đối với những trường hợp bạn sẽ có sự kết hợp giữa các đối số liên tục và các đối số khác nhau, nói chung có hai cách để xử lý vấn đề đó
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
1. Phương pháp từng phần
Chỉ khi các đối số khác nhau là đối số đầu tiên được hàm chấp nhận
2. Nói lại
Bằng cách xác định tất cả các đối số cho mỗi lệnh gọi hàm, điều này sẽ hoạt động đối với các đối số khác nhau ở các vị trí khác nhau
Nhược điểm
n = 100
63 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
06 sẽ chuyển đổi đối số
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
55 thành một danh sách trước khi thực hiện, gây thêm chi phí bộ nhớ
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
63 sẽ chặn chuỗi cuộc gọi cho đến khi kết quả được trả về
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]- Hãy cẩn thận với việc sử dụng bộ nhớ, đặc biệt là khi thời gian lặp lại lâu hơn
n = 100
63 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]n = 100
06 không hỗ trợ kwargs, vì vậy bạn cần sử dụng Phương pháp lặp lại ở trên cho tất cả các đối số hoặc không có gì rõ ràng trong thư viện đa xử lý có thể giúp bạn
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
STARMAP
n = 1004
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
STARMAP_ASYNC
n = 1005Bảng xếp hạng cuối cùng
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Từ bảng trên, chúng ta có thể thấy rằng khi được sử dụng đúng cách, đa luồng có thể tăng tốc tác vụ nặng I/O đơn giản của chúng ta. Những con số này thu được trên một phiên bản EC2 ở trạng thái không hoạt động, nghĩa là rất có thể nó sẽ khác với những gì bạn sẽ nhận được. Điều đó đang được nói,
n = 10041 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10075 đã liên tục vượt trội so với phần còn lại dựa trên kinh nghiệm và thử nghiệm của tôi, vì vậy nếu bạn muốn thử đa luồng,
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10041 và
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
n = 10075 sẽ là lựa chọn tốt nhất của bạnBạn cũng có thể thích…
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]
Logic có điều kiện hiệu quả trên Pandas DataFrames
Đã đến lúc ngừng quá phụ thuộc vào. iterrows[] và. áp dụng[]
hướng tới khoa học dữ liệu. com
7 cách dễ dàng để cải thiện quy trình làm việc khoa học dữ liệu của bạn
Những mẹo tôi đã học được khi làm việc với tư cách là Nhà khoa học dữ liệu
hướng tới khoa học dữ liệu. com
Thuật toán tìm kiếm gốc hiệu quả trong Python
Triển khai các thuật toán tìm kiếm hiệu quả để tìm gốc và tối ưu hóa trong Python
hướng tới khoa học dữ liệu. com
Trước khi bạn đi…Trong phần tiếp theo của loạt bài này, chúng ta sẽ xem xét lý do tại sao
n = 1006 có thể không đủ tốt cho công việc hàng ngày của chúng ta và cũng sẽ xem qua một số giải pháp thay thế khác, hy vọng sẽ giúp bạn tăng tốc mã của mình. Hãy cho tôi biết nếu bạn đã học được điều gì mới từ điều này. Và xin vui lòng cho tôi biết nếu có những thủ thuật gọn gàng khác mà tôi đã bỏ lỡ
data = range[n]# for loop
%%timeit -n 3
for i in data:
func[i]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]# for loop with tqdm
%%capture capture
%%timeit -n 3
for i in tqdm[data]:
func[i]
print[capture.stdout.strip[]]>>> 7.93 s ± 67.5 ms per loop [mean ± std. dev. of 7 runs, 3 loops each]