Hướng dẫn is zip faster than for loop python? - zip có nhanh hơn for loop python không?

10 phút đọc

Hướng dẫn is zip faster than for loop python? - zip có nhanh hơn for loop python không?

Giới thiệu

Có rất nhiều thông tin về cách tăng tốc mã Python. Một số tiểu bang xoay quanh các thư viện tận dụng các thư viện như Cython trong khi những người khác đề xuất một cách làm điều này, chứ không phải cách tiếp cận mã hóa. Một ví dụ về cái sau là sử dụng các triển khai vector hóa thay vì cho các vòng lặp. Có rất nhiều người làm điều này, không phải là chiến lược của người Viking mà tôi quyết định chỉ tập trung vào một vài chiến lược mà tôi phát hiện ra trong phần liên kết bên dưới.

Mục đích ban đầu của tôi chỉ là để kiểm tra các xác nhận. Tuy nhiên, khi tôi thu thập dữ liệu thử nghiệm về các phương pháp khác nhau, tôi trở nên tò mò về một tuyên bố khác mà tôi thường nghe: Python 3 nhanh hơn Python 2. Vì vậy, tôi đã thực hiện các phương pháp thử nghiệm chính xác trong Python 2.7 (PY27) và Python 3.5 (PY35) , ảnh hưởng đến các thay đổi cần thiết như sử dụng XRange cho PY27 và phạm vi cho PY35. Tất cả các thí nghiệm của tôi cũng như thời gian và các lô tương ứng có thể được tìm thấy ở đây: Notebook PY27 và Notebook PY35.

Các lô có trong bài viết này mô tả kết quả của các thí nghiệm của tôi cho Python 3 và được dán nhãn như vậy.

Để biết thông tin chi tiết bao gồm phương pháp và giá trị định lượng cho thời gian cũng như chi tiết về Python 2, vui lòng xem lại các sổ ghi chép được liên kết ở trên.

Bài này được chia thành hai phần. Trong Phần 1, tôi sẽ so sánh hai cách tiếp cận tương xứng với việc làm điều này, không phải logic đó để xem liệu có sự khác biệt đáng kể hay không và nếu vậy, cách tiếp cận nào tốt hơn. Trong Phần 2, tôi sẽ so sánh Python 2 và Python 3 để xem liệu có sự tin cậy cho tuyên bố rằng Python 3 thực sự nhanh hơn không.Part 1, I will compare two approaches commensurate with the “do this, not that” logic to see if there is a substantial difference and, if so, which approach is better. In Part 2, I will compare Python 2 and Python 3 to see if there is credence to the claim that Python 3 is indeed faster.

Phần 1: So sánh các phương pháp

Trong phần này, tôi sẽ mô tả và so sánh các phương pháp tiếp cận sau:

  • Lặp lại một bộ sưu tập
  • Vòng lặp qua một bộ sưu tập & chỉ số
  • Lặp qua hai bộ sưu tập
  • Sắp xếp danh sách theo thứ tự ngược lại
  • Nối dây
  • Thư viện tiêu chuẩn
  • ListExp vs GenExp
  • Dấu chấm

Lặp lại một bộ sưu tập

Vòng lặp qua một bộ sưu tập & chỉ số

animals = ['aardvark', 'bee', 'cat', 'dog']
[animals[i] for i in range(len(animals))]

Lặp qua hai bộ sưu tập

Sắp xếp danh sách theo thứ tự ngược lại

animals = ['aardvark', 'bee', 'cat', 'dog']
[animal for animal in animals]

Nối dây

Thư viện tiêu chuẩn

Hướng dẫn is zip faster than for loop python? - zip có nhanh hơn for loop python không?

Vòng lặp qua một bộ sưu tập & chỉ số

Lặp qua hai bộ sưu tập

# Approach #1
animals = ['aardvark', 'bee', 'cat', 'dog']
[(i, animals[i]) for i in range(len(animals))]

# Approach #2
animals = ['aardvark', 'bee', 'cat', 'dog']
[(i, animals) for i in enumerate(animals)]

Sắp xếp danh sách theo thứ tự ngược lại

Hướng dẫn is zip faster than for loop python? - zip có nhanh hơn for loop python không?

Lặp qua hai bộ sưu tập

Sắp xếp danh sách theo thứ tự ngược lại

Approach #1
animals = ['aardvark', 'bee', 'cat', 'dog']
flowers = ['allium', 'bellflower', 'crocus', 'dahlia']
[(animals[i], flowers[i]) for i in range(min(len(animals), len(flowers)))]

Approach #2
animals = ['aardvark', 'bee', 'cat', 'dog']
flowers = ['allium', 'bellflower', 'crocus', 'dahlia']
[(animal, flower) for animal, flower in zip(animals, flowers)]

Nối dây

Hướng dẫn is zip faster than for loop python? - zip có nhanh hơn for loop python không?

Sắp xếp danh sách theo thứ tự ngược lại

Nối dây

Approach #1
animals = ['bee', 'dog', 'cat', 'aardvark']
[animals[i] for i in range(len(animals)-1, -1, -1)]

Thư viện tiêu chuẩn

ListExp vs GenExp

Hướng dẫn is zip faster than for loop python? - zip có nhanh hơn for loop python không?

Nối dây

Nói rằng tôi muốn lặp qua và nối các chuỗi của tôi như tôi sẽ có một danh sách. Nếu bạn quen thuộc với các chuỗi Python, bạn sẽ biết rằng một chuỗi mới được tạo, không thực sự được gắn vào chuỗi gốc. Thật tốt khi biết nếu bạn chưa có. Vì vậy, hãy để Lôi nhìn vào hai cách tiếp cận.

Approach #1
my_string = ""
mylist = list('abcdefghijklmnopqrstuvwxyz')
for item in mylist: my_string += item

Approach #2
my_string = ""
mylist = list('abcdefghijklmnopqrstuvwxyz')
my_string = "".join([item for item in mylist])

Đầu tiên có lẽ dễ dàng hơn để quấn đầu của bạn xung quanh trừ khi bạn đã làm việc với chức năng String.join () của bạn trước đây. Vậy cái nào nhanh hơn? Có vẻ như cách tiếp cận đầu tiên có thể nhanh hơn. Tuy nhiên, tôi đang gọi kết quả này không có kết quả. Tại sao? Tôi sẽ bỏ qua các chi tiết triển khai nhưng phiên bản ngắn là tôi chỉ có thể thời gian một lần chạy duy nhất cho mỗi phương pháp sử dụng %thời gian thay vì thời gian nhiều lần chạy. Do đó, kết quả là nghi vấn. Tôi dự định quay lại trong tương lai để tiến hành một bài kiểm tra kỹ lưỡng hơn.

Thư viện tiêu chuẩn

Thư viện tiêu chuẩn Python sườn được hoàn thiện với các chức năng tích hợp. Yêu cầu ở đây là các chức năng tích hợp này được tối ưu hóa cao và do đó, nhanh hơn đáng kể so với phương pháp lập trình thuần túy. Trong trường hợp không rõ ràng, chúng ta hãy nhìn vào một ví dụ cụ thể. Giả sử tôi muốn tạo một danh sách lưu trữ tổng tích lũy của các số nguyên liên tiếp. Vì vậy, nếu tập hợp các số nguyên của tôi là [0, 1, 2, 3], danh sách được tạo của tôi sẽ là [0, 1, 3, 6]. Dưới đây là hai cách tiếp cận đã được thử nghiệm.

animals = ['aardvark', 'bee', 'cat', 'dog']
[animal for animal in animals]
0

animals = ['aardvark', 'bee', 'cat', 'dog']
[animal for animal in animals]
1

Cái nào nhanh hơn? Trong trường hợp này, cách tiếp cận thứ hai cho cả hai phiên bản Python nhanh hơn. Một kết quả thú vị được thể hiện, mặc dù. Ở đây chúng ta thấy một sự khác biệt khác giữa PY27 và PY35. PY27 chỉ cho thấy sự cải thiện nhẹ trong cách tiếp cận thứ hai, ngay cả khi nó mở rộng quy mô. Tuy nhiên, PY35 không chỉ chạy nhanh hơn nhiều với cách tiếp cận hai (nano giây thay vì mili giây hoặc giây), mà còn được chia tỷ lệ trong thời gian không đổi. Đó là một sự khác biệt lớn! Có thể có một số sự tin cậy cho tuyên bố rằng Python 3 nhanh hơn Python 2.

Hướng dẫn is zip faster than for loop python? - zip có nhanh hơn for loop python không?

ListExp vs GenExp

Tôi sẽ cho rằng bạn đã quen thuộc với các biểu thức danh sách (ListExp) tại thời điểm này. Biểu thức của máy phát (GenEXP) có thể hoặc không phải là mới đối với bạn. Để biết mô tả chuyên sâu, xem tài liệu này. Một trích dẫn chính từ tài liệu đó là:

Biểu thức của máy phát là một hiệu suất cao, tổng quát hóa bộ nhớ của toàn bộ danh sách.

Tài liệu cũng tiếp tục nói:

Khi khối lượng dữ liệu phát triển lớn hơn, các biểu thức của máy phát có xu hướng hoạt động tốt hơn [so với các biểu thức danh sách] vì chúng không làm cạn kiệt bộ nhớ bộ nhớ cache và chúng cho phép Python sử dụng lại các đối tượng giữa các lần lặp.

Bây giờ, hãy thử nghiệm các xác nhận đó bằng cách tận dụng ví dụ tổng tích lũy từ phần cuối cùng.

animals = ['aardvark', 'bee', 'cat', 'dog']
[animal for animal in animals]
2

animals = ['aardvark', 'bee', 'cat', 'dog']
[animal for animal in animals]
3

Biểu thức của máy phát chắc chắn dễ sử dụng vì chúng trông gần giống với các biểu thức liệt kê. Vậy họ có biểu diễn như được chào hàng không? Trong cả hai phiên bản, câu trả lời là không rõ ràng có! Danh sách các biểu thức được chia tỷ lệ với dữ liệu trong khi các biểu thức máy phát được chia tỷ lệ theo thời gian không đổi cho cả hai phiên bản. Một kết quả giao thoa là các biểu thức máy phát PY27 nhanh hơn một chút so với PY35. Tôi không rõ lý do tại sao đó là trường hợp. Đáng để khám phá trong tương lai.

Cập nhật: Biểu thức của máy phát dường như đánh giá một cách lười biếng, nghĩa là chúng không làm gì cho đến khi bạn kêu gọi một số hành động. Điều này sẽ giải thích tại sao họ dường như mở rộng quy mô vô cùng. Big Takeaway là các biểu thức máy phát cho phép bạn xử lý dữ liệu giành được sự phù hợp với bộ nhớ cũng như một luồng dữ liệu vô hạn. Danh sách biểu thức phân tích trong cả hai kịch bản.

Hướng dẫn is zip faster than for loop python? - zip có nhanh hơn for loop python không?

Dấu chấm

Chiến lược cuối cùng mà tôi đã thử nghiệm phải làm với thứ này gọi là Dots. Dots chỉ là một cách khác để nói phương pháp. Thiếu một cách rõ ràng để nêu chiến lược này bằng lời nói, thay vào đó tôi sẽ có được quyền tiếp cận, điều này nên tự giải thích.

animals = ['aardvark', 'bee', 'cat', 'dog']
[animal for animal in animals]
4

animals = ['aardvark', 'bee', 'cat', 'dog']
[animal for animal in animals]
5

Có một sự khác biệt? Cả PY27 và PY35 đều thể hiện sự khác biệt cận biên bị sai lệch đối với cách tiếp cận thứ hai là hiệu suất hơn. Bằng chứng dường như chỉ ra rằng có thể có một hiệu suất tăng nhưng dường như không đáng để nỗ lực đưa ra một số kết quả kịch tính mà chúng tôi đã thấy trong các danh mục khác.

Hướng dẫn is zip faster than for loop python? - zip có nhanh hơn for loop python không?

Phần 2: Python 2 vs Python 3

Trong phần giới thiệu, tôi đã trình bày một tuyên bố mà tôi thường nghe. Cụ thể, Python 3 nhanh hơn Python 2.

Trước hết, hãy để tôi chỉ nói rằng trong khi tôi thu thập một số bằng chứng thực nghiệm bằng cách kiểm tra một vài khẳng định, việc lấy mẫu thí nghiệm nhỏ này rõ ràng là không đủ để chính thức khai báo. Điều đó nói rằng, có bằng chứng cho thấy một số hoạt động bên trong của Python 3 được tối ưu hóa hơn nhiều và do đó, Python 3 nhanh hơn trong một số vấn đề. Lấy ví dụ ví dụ thư viện tiêu chuẩn bằng cách sử dụng map (). Chúng tôi đã thấy một sự khác biệt rất lớn khi so sánh PY27 và PY35 khi PY35 chia tỷ lệ trong thời gian không đổi và PY27 thì không. Trong vòng lặp qua hai thử nghiệm bộ sưu tập, PY35 cũng hoạt động tốt hơn vì zip () là một trình lặp trong PY35.

Bản tóm tắt

Có nhiều cách để tăng tốc mã Python. Các thư viện nhanh chóng như Cython hoặc Numba tồn tại. Tuy nhiên, tôi quyết định tập trung vào các kỹ thuật mã hóa trong bài viết này. Như vậy, tôi đã xác định một vài kỹ thuật trông đầy hứa hẹn và chạy các thí nghiệm để xác định xem liệu khẳng định rằng chúng dẫn đến mã nhanh hơn trên thực tế. Là một tiện ích bổ sung, tôi muốn khám phá tuyên bố thường được khẳng định rằng Python 3 nhanh hơn Python 2. Không có thêm ADO, đây là kết quả ở định dạng điểm đạn cổ điển:

  • Tránh sử dụng chỉ mục Danh sách Danh sách để truy cập các mục của nó khi lặp qua bộ sưu tập
  • Sử dụng Enumerate () đẹp hơn nhưng không nhanh hơn để lặp qua bộ sưu tập và chỉ số
  • Tận dụng phiên bản Python của bạn khi lặp qua hai bộ sưu tập - sử dụng itertools cho Python 2
  • Sử dụng các chức năng tích hợp bất cứ khi nào có thể
  • Làm thế nào bạn nối các chuỗi có thể quan trọng ở quy mô nhưng thử nghiệm của tôi là không thuyết phục
  • Quên danh sách biểu thức ở quy mô; biểu thức máy phát nhạc rock thay thế
  • Dots có thể mang lại cho bạn mức tăng hiệu suất cận biên nhưng có thể không đáng để nỗ lực
  • Khi Python 3 tốt hơn Python 2, nó tốt hơn nhiều

Là người dùng Python 2 lâu dài, thử nghiệm này đã khiến tôi hào hứng hơn nhiều về Python 3. Vâng, tôi biết Python 3 là tương lai nhưng bây giờ tôi có một cái gì đó hữu hình để nắm bắt - bằng chứng rằng các khía cạnh thực sự nhanh hơn và có thể dẫn đến nhanh hơn mã số. Nếu không có gì khác, khi thực hiện các thí nghiệm của riêng tôi đã cung cấp cho tôi chất xúc tác để cuối cùng thực hiện quá trình chuyển đổi.

Tóm lại, đây là một dự án thú vị khiến tôi suy nghĩ. Có rất nhiều con đường còn lại chưa được khám phá và dự án này đã đưa ra nhiều câu hỏi hơn so với tôi đã trả lời cho tôi, nhưng bây giờ tôi cảm thấy tự tin hơn nhiều về năng lực của Python 3.


Như mọi khi, tôi hy vọng bạn tìm thấy sự khai sáng này, giải trí hoặc cả hai. Nếu bạn có câu hỏi, nhận xét hoặc phản hồi, xin vui lòng cho tôi biết.


Liên kết

4 Mẹo tối ưu hóa hiệu suất cho mã Python nhanh hơn Pythonspeed Mẹo hiệu suất 6 Mẹo hiệu suất Python
PythonSpeed Performance Tips
6 Python Performance Tips

Cách nhanh nhất để lặp trong Python là gì?

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ố.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.

Zip làm gì trong vòng lặp Loop?

Hàm zip () của Python tạo ra một trình lặp sẽ tổng hợp các phần tử từ hai hoặc nhiều vòng lặp. Bạn có thể sử dụng trình lặp kết quả để giải quyết nhanh chóng và nhất quán các vấn đề lập trình phổ biến, như tạo từ điển.creates an iterator that will aggregate elements from two or more iterables. You can use the resulting iterator to quickly and consistently solve common programming problems, like creating dictionaries.

Tại sao bạn sử dụng phương thức zip () trong Python?

zip () trong phương thức python python zip () có thể sử dụng được hoặc các thùng chứa và trả về một đối tượng lặp duy nhất, có các giá trị được ánh xạ từ tất cả các container.Nó được sử dụng để ánh xạ chỉ số tương tự của nhiều container để chúng có thể được sử dụng chỉ bằng cách sử dụng một thực thể duy nhất.to map the similar index of multiple containers so that they can be used just using a single entity.

Sự khác biệt giữa liệt kê và zip trong Python là gì?

Hàm liệt kê () trả về các chỉ mục của tất cả các mục trong Iterables (danh sách, từ điển, bộ, v.v.) trong khi hàm zip () được sử dụng để tổng hợp hoặc kết hợp nhiều lần lặp. whereas the zip() function is used to aggregate, or combine, multiple iterables.