Hướng dẫn are for loops faster in python? - cho các vòng lặp nhanh hơn trong python?

Mục lục:

      • Báo cáo vấn đề
      • Sự chuẩn bị
      • Vòng lặp đơn giản
      • Vòng lồng nhau
      • Kết quả tóm tắt
      • Kết luận

Python là một trong những ngôn ngữ lập trình phổ biến nhất hiện nay. Nó có một ngôn ngữ cấp cao và được giải thích với cú pháp thanh lịch và có thể đọc được. Tuy nhiên, Python thường chậm hơn đáng kể so với Java, C#và đặc biệt là C, C ++ hoặc Fortran. Đôi khi các vấn đề về hiệu suất và tắc nghẽn có thể ảnh hưởng nghiêm trọng đến khả năng sử dụng của các ứng dụng.

May mắn thay, trong hầu hết các trường hợp, có những giải pháp để cải thiện hiệu suất của các chương trình Python. Có những lựa chọn mà các nhà phát triển có thể thực hiện để cải thiện tốc độ mã của họ. Ví dụ, lời khuyên chung là sử dụng các thói quen python hoặc bên thứ ba được tối ưu hóa, thường được viết bằng C hoặc Cython. Bên cạnh đó, nó nhanh hơn để làm việc với các biến cục bộ so với Globals, do đó, nó là một thực tế tốt để sao chép một biến toàn cầu vào một địa phương trước vòng lặp. Và như thế.

Cuối cùng, luôn có khả năng viết các chức năng Python của riêng mình trong C, C ++ hoặc Cython, gọi chúng từ ứng dụng và thay thế các thói quen tắc nghẽn Python. Nhưng đây thường là một giải pháp cực đoan và hiếm khi cần thiết cho thực tiễn.

Thông thường các vấn đề về hiệu suất phát sinh khi sử dụng các vòng python, đặc biệt là với một số lượng lớn các lần lặp. Có một số thủ thuật hữu ích để cải thiện mã của bạn và làm cho nó chạy nhanh hơn, nhưng điều đó vượt quá phạm vi ở đây.

Bài viết này so sánh hiệu suất của một số phương pháp khi tổng hợp hai phần tử khôn ngoan:

  • Sử dụng vòng lặp trong khi
  • Sử dụng vòng lặp cho
  • Sử dụng vòng lặp cho toàn bộ danh sách
  • Sử dụng thư viện của bên thứ ba
    n = 1_000
    x, y = random.sample(r, n), random.sample(r, n)
    3

Tuy nhiên, hiệu suất không phải là mối quan tâm duy nhất khi phát triển phần mềm. Hơn nữa, theo Donald Knuth trong nghệ thuật lập trình máy tính, tối ưu hóa sớm là gốc rễ của mọi điều ác (hoặc ít nhất là hầu hết) trong lập trình. Rốt cuộc, khả năng đọc của người Viking đếm được, như đã nêu trong Zen of Python của Tim Peters.

Báo cáo vấn đề

Chúng tôi sẽ cố gắng tổng hợp hai phần tử khôn ngoan. Nói cách khác, chúng tôi sẽ lấy hai chuỗi (danh sách hoặc mảng) có cùng kích thước và tạo cái thứ ba với các phần tử thu được bằng cách thêm các phần tử tương ứng từ các đầu vào.

Sự chuẩn bị

Vòng lặp đơn giản

import random
r = [random.randrange(100) for _ in range(100_000)]

Vòng lồng nhau

Kết quả tóm tắt

Vòng lặp đơn giản

Vòng lồng nhau

Kết quả tóm tắt
Kết luận

n = 1_000
x, y = random.sample(r, n), random.sample(r, n)

Python là một trong những ngôn ngữ lập trình phổ biến nhất hiện nay. Nó có một ngôn ngữ cấp cao và được giải thích với cú pháp thanh lịch và có thể đọc được. Tuy nhiên, Python thường chậm hơn đáng kể so với Java, C#và đặc biệt là C, C ++ hoặc Fortran. Đôi khi các vấn đề về hiệu suất và tắc nghẽn có thể ảnh hưởng nghiêm trọng đến khả năng sử dụng của các ứng dụng.

May mắn thay, trong hầu hết các trường hợp, có những giải pháp để cải thiện hiệu suất của các chương trình Python. Có những lựa chọn mà các nhà phát triển có thể thực hiện để cải thiện tốc độ mã của họ. Ví dụ, lời khuyên chung là sử dụng các thói quen python hoặc bên thứ ba được tối ưu hóa, thường được viết bằng C hoặc Cython. Bên cạnh đó, nó nhanh hơn để làm việc với các biến cục bộ so với Globals, do đó, nó là một thực tế tốt để sao chép một biến toàn cầu vào một địa phương trước vòng lặp. Và như thế.

%%timeit
i, z = 0, []
while i < n:
    z.append(x[i] + y[i])
    i += 1

Cuối cùng, luôn có khả năng viết các chức năng Python của riêng mình trong C, C ++ hoặc Cython, gọi chúng từ ứng dụng và thay thế các thói quen tắc nghẽn Python. Nhưng đây thường là một giải pháp cực đoan và hiếm khi cần thiết cho thực tiễn.

Thông thường các vấn đề về hiệu suất phát sinh khi sử dụng các vòng python, đặc biệt là với một số lượng lớn các lần lặp. Có một số thủ thuật hữu ích để cải thiện mã của bạn và làm cho nó chạy nhanh hơn, nhưng điều đó vượt quá phạm vi ở đây.

Bài viết này so sánh hiệu suất của một số phương pháp khi tổng hợp hai phần tử khôn ngoan:

Sử dụng vòng lặp trong khi

%%timeit
z = []
for i in range(n):
    z.append(x[i] + y[i])

Cuối cùng, luôn có khả năng viết các chức năng Python của riêng mình trong C, C ++ hoặc Cython, gọi chúng từ ứng dụng và thay thế các thói quen tắc nghẽn Python. Nhưng đây thường là một giải pháp cực đoan và hiếm khi cần thiết cho thực tiễn.

Thông thường các vấn đề về hiệu suất phát sinh khi sử dụng các vòng python, đặc biệt là với một số lượng lớn các lần lặp. Có một số thủ thuật hữu ích để cải thiện mã của bạn và làm cho nó chạy nhanh hơn, nhưng điều đó vượt quá phạm vi ở đây.

Bài viết này so sánh hiệu suất của một số phương pháp khi tổng hợp hai phần tử khôn ngoan:

Sử dụng vòng lặp trong khi

%%timeit
z = [x[i] + y[i] for i in range(n)

Cuối cùng, luôn có khả năng viết các chức năng Python của riêng mình trong C, C ++ hoặc Cython, gọi chúng từ ứng dụng và thay thế các thói quen tắc nghẽn Python. Nhưng đây thường là một giải pháp cực đoan và hiếm khi cần thiết cho thực tiễn.

Thông thường các vấn đề về hiệu suất phát sinh khi sử dụng các vòng python, đặc biệt là với một số lượng lớn các lần lặp. Có một số thủ thuật hữu ích để cải thiện mã của bạn và làm cho nó chạy nhanh hơn, nhưng điều đó vượt quá phạm vi ở đây.

Bài viết này so sánh hiệu suất của một số phương pháp khi tổng hợp hai phần tử khôn ngoan:

Sử dụng vòng lặp trong khi
Sử dụng vòng lặp cho

Sử dụng vòng lặp cho toàn bộ danh sách

Sử dụng thư viện của bên thứ ba

n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3

x_, y_ = np.array(x, dtype=np.int64), np.array(y, dtype=np.int64)

Tóm tắt hai mảng

n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3 X_ và Y_ phần tử khôn ngoan cũng dễ dàng như x_ + y_. Nhưng hãy để kiểm tra hiệu suất:

Đầu ra là:

1,03 Pha ± 5,09 ns mỗi vòng (trung bình ± std. Dev. Của 7 lần chạy, 1000000 vòng mỗi)

Điều đó nhanh hơn gần 85 lần so với khi chúng tôi sử dụng toàn bộ danh sách. Và mã cực kỳ đơn giản và thanh lịch.

n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3 Mảng có thể là một lựa chọn tốt hơn nhiều để làm việc với các mảng lớn. Lợi ích hiệu suất thường lớn hơn khi dữ liệu lớn hơn.

Nó có thể thậm chí còn tốt hơn. Nếu chúng tôi ổn với việc sử dụng số nguyên 32 bit thay vì 64 bit, chúng tôi có thể lưu cả bộ nhớ và thời gian trong một số trường hợp:

x_, y_ = np.array(x, dtype=np.int32), np.array(y, dtype=np.int32)

Chúng ta có thể thêm hai mảng này như trước:

Đầu ra là:

1,03 Pha ± 5,09 ns mỗi vòng (trung bình ± std. Dev. Của 7 lần chạy, 1000000 vòng mỗi)

Điều đó nhanh hơn gần 85 lần so với khi chúng tôi sử dụng toàn bộ danh sách. Và mã cực kỳ đơn giản và thanh lịch.

n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3 Mảng có thể là một lựa chọn tốt hơn nhiều để làm việc với các mảng lớn. Lợi ích hiệu suất thường lớn hơn khi dữ liệu lớn hơn.

Nó có thể thậm chí còn tốt hơn. Nếu chúng tôi ổn với việc sử dụng số nguyên 32 bit thay vì 64 bit, chúng tôi có thể lưu cả bộ nhớ và thời gian trong một số trường hợp:

Chúng ta có thể thêm hai mảng này như trước:

814 ns ± 5,8 ns mỗi vòng (trung bình ± std. Dev. Của 7 lần chạy, 1000000 vòng mỗi)
Các kết quả thu được khi N lớn hơn, đó là 10_000 và 100_000 được hiển thị trong bảng bên dưới. Chúng cho thấy các mối quan hệ tương tự, như trong trường hợp này, với hiệu suất tăng cao hơn khi sử dụng
n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3.

m, n = 100, 1_000
x = [random.sample(r, n) for _ in range(m)]
y = [random.sample(r, n) for _ in range(m)]

Vòng lồng nhau

%%timeit
i, z = 0, []
while i < m:
    j, z_ = 0, []
    while j < n:
        z_.append(x[i][j] + y[i][j])
        j += 1
    z.append(z_)
    i += 1

Đầu ra là:

Bây giờ, hãy so sánh các vòng python lồng nhau.

%%timeit
z = []
for i in range(m):
    z_ = []
    for j in range(n):
         z_.append(x[i][j] + y[i][j])
    z.append(z_)

Đầu ra là:

Sử dụng Python thuần túy

n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
0

Đầu ra là:

Chúng tôi sẽ làm việc với hai danh sách được gọi là X và Y một lần nữa. Mỗi trong số chúng sẽ chứa 100 danh sách bên trong với 1.000 phần tử số nguyên giả. Do đó, X và Y thực sự sẽ đại diện cho các ma trận với 100 hàng và 1.000 cột:

Hãy cùng xem hiệu suất của việc thêm chúng bằng cách sử dụng hai vòng trong khi các vòng lặp:

19,7 ms ± 271 Pha mỗi vòng (trung bình ± std.

16,4 ms ± 303 Pha mỗi vòng (trung bình ± std.
12,1 ms ± 99,4 Pha mỗi vòng (trung bình ± std. Dev. Của 7 lần chạy, 100 vòng mỗi)

Chúng ta có thể thấy rằng trong trường hợp các vòng lặp lồng nhau, các toàn bộ danh sách nhanh hơn thông thường cho các vòng lặp, nhanh hơn trong khi.

Trong trường hợp này, chúng tôi có 100.000 phần tử số nguyên (100 × 1.000) trong mỗi danh sách. Ví dụ này chậm hơn một chút so với cái có 100.000 phần tử và một vòng lặp duy nhất. Đó là kết luận cho cả ba cách tiếp cận (danh sách toàn diện, thông thường cho và trong khi các vòng lặp).

Đầu ra là:

Sử dụng python với numpy

x_, y_ = np.array(x, dtype=np.int32), np.array(y, dtype=np.int32)

n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3 là tuyệt vời để làm việc với các mảng đa chiều. Hãy để sử dụng X và Y để tạo các mảng
n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3 tương ứng của số nguyên 64 bit:

Đầu ra là:

x_, y_ = np.array(x, dtype=np.int64), np.array(y, dtype=np.int64)

Và hãy để kiểm tra hiệu suất:

69,9 Pha ± 909 ns mỗi vòng (trung bình ± std. Nhưng nó có thể thậm chí còn nhanh hơn nếu chúng ta sử dụng số nguyên 32 bit:

Kiểm tra hiệu suất được thực hiện như trước:34,3 Pha ± 44,6 ns mỗi vòng (trung bình ± std. Dev. 7 lần chạy, 10000 vòng mỗi) nhanh hơn hai lần so với số nguyên 64 bit.Kết quả tóm tắtBảng này tóm tắt các kết quả thu được:Số lượng phần tử, M × N
1 × 1.0001 × 10.0001 × 100.000100 × 1.000Python
%%timeit
i, z = 0, []
while i < n:
    z.append(x[i] + y[i])
    i += 1
6
160 ss1,66 ms17.0 ms19,7 msPython
%%timeit
i, z = 0, []
while i < n:
    z.append(x[i] + y[i])
    i += 1
7
122 s1,24 ms13,4 ms16,4 msPython
%%timeit
i, z = 0, []
while i < n:
    z.append(x[i] + y[i])
    i += 1
7 với danh sách hiểu biết
87,2 s894 s8,92 ms12.1 ms
n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3 với số nguyên 64 bit
1,03 s6,36 s71,9 s69,9 s
n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3 với số nguyên 32 bit

814 ns

2,87 s

34,1 s

34,3 s

Kết luận

Bài viết này so sánh hiệu suất của các vòng python khi thêm hai danh sách hoặc mảng phần tử khôn ngoan. Kết quả cho thấy rằng các toàn bộ danh sách nhanh hơn thông thường cho vòng lặp, nhanh hơn vòng lặp trong khi. Các vòng đơn giản nhanh hơn một chút so với các vòng lồng nhau trong cả ba trường hợp.

n = 1_000
x, y = random.sample(r, n), random.sample(r, n)
3 cung cấp các thói quen và nhà khai thác có thể giảm đáng kể lượng mã và tăng tốc độ thực thi. Nó đặc biệt hữu ích khi làm việc với các mảng đơn và đa chiều.

Xin lưu ý rằng các kết luận hoặc quan hệ giữa các kết quả thu được ở đây không được áp dụng, hợp lệ hoặc hữu ích trong mọi trường hợp! Chúng được trình bày để minh họa. Cách thích hợp để xử lý sự thiếu hiệu quả là khám phá các tắc nghẽn và thực hiện các bài kiểm tra riêng.

Bài đọc liên quan

Thông tin thêm về Radek Fabisiak

Nếu bạn thích nó chia sẻ và bình luận!

Vòng lặp nào hiệu quả nhất trong Python?

Một cách nhanh hơn để lặp trong Python là sử dụng các chức năng tích hợp. Trong ví dụ của chúng tôi, chúng tôi có thể thay thế vòng lặp cho chức năng tổng. Hàm này sẽ tổng hợp các giá trị bên trong phạm vi số. Mã trên mất 0,84 giây.using built-in functions. In our example, we could replace the for loop with the sum function. This function will sum the values inside the range of numbers. The code above takes 0.84 seconds.

Có phải các vòng lặp nhanh hơn trong Python hơn R?

Tổng thời lượng của tập lệnh R là khoảng 11 phút và 12 giây, khoảng 7,12 giây mỗi vòng.Tổng thời lượng của tập lệnh Python là khoảng 2 phút và 2 giây, khoảng 1,22 giây mỗi vòng.Mã Python nhanh hơn 5,8 lần so với thay thế R!The Python code is 5.8 times faster than the R alternative!

Cái nào nhanh hơn trong khi hoặc cho vòng lặp?

Sử dụng cho: % Thời gian trôi qua: 0,0010001659 giây.Sử dụng trong khi: % Thời gian trôi qua: 0,026000023 giây.Lý do chính mà trong khi chậm hơn nhiều là vì vòng lặp trong khi kiểm tra điều kiện sau mỗi lần lặp, vì vậy nếu bạn định viết mã này, chỉ cần sử dụng một vòng lặp cho LOOP thay thế.While is much slower is because the while loop checks the condition after each iteration, so if you are going to write this code, just use a for loop instead.

Loại vòng lặp nào nhanh hơn?

Vòng lặp là nhanh nhất nhưng có thể đọc được kém.Các foreach là nhanh, và lặp lại có thể kiểm soát được.Các trò chơi dành cho thời gian, nhưng nó ngọt ngào hơn.Những người cho trong thời gian, do đó ít thuận tiện hơn.for loop is the fastest but poorly readable. The foreach is fast, and iteration is controllable. The for…of takes time, but it's sweeter. The for…in takes time, hence less convenient.