Hướng dẫn is python slow compared to c? - python có chậm so với c không?

Cpython đặc biệt chậm vì nó không chỉ có trình tối ưu hóa thời gian (vì đó là việc thực hiện tham chiếu và chọn sự đơn giản hơn hiệu suất trong một số trường hợp nhất định). Unladen Swallow là một dự án để thêm một JIT được hỗ trợ bởi LLVM vào Cpython và đạt được tốc độ tăng tốc lớn. Có thể Jython và Ironpython nhanh hơn nhiều so với Cpython cũng như chúng được hỗ trợ bởi các máy ảo được tối ưu hóa mạnh (JVM và .NET CLR).

Tuy nhiên, một điều được cho là sẽ khiến Python chậm hơn, là nó được gõ linh hoạt và có hàng tấn tra cứu cho mỗi truy cập thuộc tính.

Chẳng hạn, việc gọi f trên một đối tượng A sẽ gây ra các tra cứu có thể xảy ra trong __dict__, các cuộc gọi đến __getattr__, v.v., sau đó gọi __call__ trên đối tượng có thể gọi f.

Đối với việc gõ động, có nhiều tối ưu hóa có thể được thực hiện nếu bạn biết loại dữ liệu bạn đang xử lý. Ví dụ: trong Java hoặc C, nếu bạn có một loạt các số nguyên bạn muốn tổng hợp, mã lắp ráp cuối cùng có thể đơn giản như tìm nạp giá trị tại chỉ mục i, thêm nó vào accumulator, sau đó tăng i.

Trong Python, điều này rất khó để làm cho mã này tối ưu. Giả sử bạn có một đối tượng phân lớp danh sách chứa ints. Trước khi thậm chí thêm bất kỳ, Python phải gọi A0, sau đó thêm nó vào "bộ tích lũy" bằng cách gọi A1, sau đó lặp lại. Hàng tấn tra cứu thay thế có thể xảy ra ở đây bởi vì một chủ đề khác có thể đã thay đổi ví dụ như phương thức A2, chỉ dẫn của thể hiện danh sách hoặc chỉ đạo của lớp, giữa các cuộc gọi để thêm hoặc getItem. Ngay cả việc tìm kiếm bộ tích lũy và danh sách (và bất kỳ biến nào bạn đang sử dụng) trong không gian tên cục bộ cũng gây ra sự tra cứu của Dict. Chi phí tương tự này áp dụng khi sử dụng bất kỳ đối tượng do người dùng xác định nào, mặc dù đối với một số loại tích hợp, nó được giảm thiểu.

Điều đáng chú ý là các loại nguyên thủy như Bigint (int trong Python 3, Long in Python 2.x), Danh sách, Set, Dict, v.v., v.v., là những gì mọi người sử dụng rất nhiều trong Python. Có hàng tấn hoạt động tích hợp trên các đối tượng này đã được tối ưu hóa đủ. Ví dụ: đối với ví dụ trên, bạn chỉ cần gọi A3 thay vì sử dụng bộ tích lũy và chỉ mục. Bám sát vào những thứ này và một chút khủng hoảng với int/float/phức tạp, bạn thường sẽ không có vấn đề về tốc độ và nếu bạn làm vậy Chỉ cần chuyển ra C (hoặc mã Java, trong Jython). Thực tế là, khi bạn mã hóa C hoặc C ++, bạn sẽ lãng phí rất nhiều thời gian để làm những việc mà bạn có thể làm trong vài giây/dòng mã Python. Tôi muốn nói rằng sự đánh đổi luôn luôn có giá trị ngoại trừ các trường hợp bạn đang làm một cái gì đó như lập trình nhúng hoặc thời gian thực và không đủ khả năng.lots of time doing things that you can do in a few seconds/lines of Python code. I'd say the tradeoff is always worth it except for cases where you are doing something like embedded or real time programming and can't afford it.

Tại sao Python chậm hơn C? Ban đầu xuất hiện trên Quora - nơi để đạt được và chia sẻ kiến ​​thức, trao quyền cho mọi người học hỏi từ người khác và hiểu rõ hơn về thế giới.

Trả lời bởi Terry Lambert, nhóm nhân Kernel của Apple Core; Dẫn đầu kỹ thuật trong một số dự án trong hơn 8 năm, trên Quora:by Terry Lambert, Apple Core OS Kernel Team; technical lead on several projects over 8 years, on Quora:

Python chậm hơn C vì nó là ngôn ngữ được giải thích.

Điều này khuếch đại số lượng hướng dẫn CPU thực tế cần thiết để thực hiện một câu lệnh nhất định.

Trong một chương trình Python, bạn có thể thêm giá trị 1 vào một biến hoặc so sánh giá trị của một biến để xem liệu nó có nhỏ hơn một giá trị nhất định, lớn hơn một giá trị nhất định hoặc bằng một giá trị nhất định, chẳng hạn như trong :

Hướng dẫn is python slow compared to c? - python có chậm so với c không?

Trong ngôn ngữ lắp ráp, bạn cũng có thể thực hiện vòng lặp này:

Hướng dẫn is python slow compared to c? - python có chậm so với c không?

Sự khác biệt là mã Python sẽ được giải thích, thay vì trực tiếp bởi CPU.

Điều này làm cho tất cả sự khác biệt trên thế giới, liên quan đến hiệu suất.

Mã Python hầu như luôn luôn chạy trong một máy ảo.

.

Một tên khác cho một máy ảo là một trình thông dịch mã byte.

Mã được giải thích luôn chậm hơn mã máy trực tiếp, bởi vì cần nhiều hướng dẫn hơn để thực hiện một hướng dẫn được giải thích hơn là thực hiện một hướng dẫn máy thực tế.

Ví dụ thời gian! Yay!

Ví dụ, hãy để Lừa lấy X += 1. Trong CPU Intel, mức tăng của thanh ghi là một OP duy nhất, có độ trễ là 1 và giá trị thông lượng qua lại là 1/3.

Nói cách khác: Nó nói về hướng dẫn CPU nhanh nhất mà nó có thể có trên bộ xử lý Intel.

Làm thế nào là x += 1 này được hoàn thành trong Python?

Để biết điều này, bạn phải biết Python hoạt động trong nội bộ như thế nào.

Trong nội bộ, Python bao gồm một tokenizer, trình phân tích từ vựng, trình tạo mã byte và trình thông dịch bytecode:

  • Tokenizer này chuyển đổi mã python đầu vào (tệp văn bản ASCII) thành luồng mã thông báo This converts input Python code (ASCII text files) into a token stream
  • Phân tích từ vựng Đây là một phần của Python quan tâm đến tất cả các không gian và thụt lề có ý nghĩa đó. Đây là nơi kiểm tra cú pháp xảy ra. This is the part of Python that cares all about those meaningful spaces and indentation. This is where syntax checking happens.
  • Trình tạo mã byte Đây là một phần của Python thực hiện các tối ưu hóa, nếu có; Bởi vì Python thực sự không phải là ngôn ngữ biên dịch, phạm vi tối ưu hóa bị hạn chế, so với các tối ưu hóa mà bạn có thể nhận được từ trình biên dịch C. This is the Part of Python that does the optimizations, if any; because Python is not actually a compile language, the range of optimizations is limited, compared to the optimizations which you might get out of a C compiler.
  • Trình thông dịch bytecode Đây là một phần của Python hoạt động trên luồng mã byte và duy trì trạng thái của máy ảo Python. This is the part of Python that operates on the bytecode stream, and maintains the state of the Python virtual machine.

Bytecode, một khi được tạo thường được lưu trong bộ nhớ.

Điều này cung cấp một cải tiến tốc độ, bởi vì điều đó có nghĩa là bạn có thể tránh lặp lại mã thông báo, phân tích từ vựng và các bước tạo mã byte cho mã mà Python đã thấy.

Vì vậy, khi chúng tôi lặp lại vòng lặp trong khi chúng tôi có thể bỏ qua mã thông báo phân tích từ vựng và các bước tạo mã byte, và chỉ cần đưa mã byte cho trình thông dịch bytecode, hết lần này đến lần khác.

Điều này là nhanh, phải không?

Trên thực tế, không.

Mặc dù sử dụng mã byte được lưu trong bộ nhớ cache, nhưng đây không giống như hoạt động nhanh như mã máy.

Một máy ảo không phải là CPU thực tế mà mã đang chạy.

Một đoạn giới thiệu ngắn đến máy ảo.

Một trong những máy ảo được sử dụng sớm nhất được gọi là hệ thống P-P-SYST, từ Đại học California, San Diego. Đó là khoảng năm 1972.

Ngay sau đó, Microsoft đã phát hành phiên bản cơ bản của họ (dựa trên Đại học Dartmouth Basic từ năm 1964), điều này đã mã hóa mã cơ bản giống như cách mà Python token hóa ngày nay. Cơ bản được lưu trữ trong bộ nhớ theo cách tương tự như mã Bytecy python được lưu trữ trong bộ nhớ sau mã hóa, mặc dù độ trễ cơ bản một số giai đoạn phân tích từ vựng cho đến khi chạy. Trong máy ảo của nó: Trình thông dịch cơ bản.

Khác với việc không có số dòng cho mỗi dòng và sử dụng khoảng cách làm kỹ thuật quản lý khối báo cáo, thay vì không có và sử dụng goto thay vào đó, Python phần lớn giống với các phiên dịch viên cơ bản mà chúng tôi đã có 40 năm trước.

Biên soạn trực tuyến so với biên dịch.

Được biên dịch UCSD Pascal không được biên dịch cho ngôn ngữ lắp ráp, như trong các ngôn ngữ được biên dịch khác vào thời điểm đó.

Thay vào đó, nó được biên dịch thành mã P.

Apple, nơi tôi làm việc, có giấy phép không thể trả lời duy nhất cho hệ thống mã P của UCSD. Đây là một sai lầm cấp phép mà UCSD không lặp lại sau này.

Hầu hết các prodos trên Apple II được viết bằng Pascal và hầu hết tất cả các mã để thực hiện QuickDraw trong Macintoshes ban đầu được viết bằng Pascal.

Vì vậy, khi bạn nghĩ về một chương trình Pascal đã biên dịch, vào thời điểm đó, bạn đã nói về mã P. Hoặc Bytecode, nếu bạn là một người hâm mộ Java hoặc Python, và muốn giả vờ bạn đã phát minh ra một cái gì đó mới.

Python cũng có khái niệm về Python đã biên soạn; Đây là mã Python đã đi qua tokenizer, trình phân tích từ vựng và trình tạo mã byte, để có được những gì bạn có trong bộ nhớ làm bộ nhớ cache, đã sẵn sàng để cung cấp cho trình thông dịch bytecode (hay còn gọi là máy ảo Python).

Bất cứ khi nào bạn thấy một tệp kết thúc bằng .py, đây là tệp văn bản ASCII có chứa mã nguồn Python.

Khi bạn thấy một tệp kết thúc bằng .pyc, đây là Python, được biên dịch.

Mã kết quả vẫn chạy trong một máy ảo.

Mã nguồn.

Một chương trình không phải là mã gốc cho đến khi nó được biên dịch và một chương trình đã thực sự được biên dịch thành mã gốc cho đến khi nó được biên dịch cho các hướng dẫn CPU nhị phân gốc trên nền tảng mà nó nhắm mục tiêu.

Điều này thường liên quan đến việc tạo mã lắp ráp thay vì mã byte, chuyển mã lắp ráp cho trình biên dịch và trình biên dịch phát ra các tệp đối tượng cụ thể của nền tảng.

Sau đó, chương trình vẫn chưa sẵn sàng để chạy, cho đến khi nó liên kết với thời gian chạy nền tảng. Một thời gian chạy thiết lập môi trường mà mã dự kiến ​​sẽ chạy và có thể cung cấp một số dịch vụ thời gian chạy như tải đối tượng động. Biên dịch C có thời gian chạy. Biên dịch C ++ có thời gian chạy.

Hầu hết, các runtimes này chỉ thiết lập môi trường và nhảy vào mã của bạn. Nói cách khác: họ có chi phí một lần.

Quá trình liên kết một tệp đối tượng được tạo với thời gian chạy (và bất kỳ thư viện hỗ trợ nào) để tạo một thực thi độc lập được gọi là liên kết trực tuyến.

Máy ảo không liên kết; gần nhất họ nhận được là tải các mô -đun bổ sung vào máy ảo. Mặc dù các mô -đun này có thể được biên dịch - trên thực tế, đây là cơ sở của một số mô -đun Python để hoạt động tốc độ trong Python Up, và đó là cơ sở của JNI (giao diện gốc Java) - các mô -đun thường được viết bằng ngôn ngữ được biên dịch, như vậy Một C hoặc C ++, hoặc nếu chúng giống như một thư viện toán học, chúng thậm chí có thể được viết trong lắp ráp.

Sau đó, một cái gì đó được biên soạn, trừ khi nó trở thành một nhị phân gốc cho nền tảng mà nó đang chạy.

Tại sao chạy trong một máy ảo làm cho bạn chậm.

Chạy trong một máy ảo yêu cầu diễn giải một byteStream, sau đó chạy mã gốc thay mặt cho byteStream.

Vì vậy, hãy để Lừa quay lại ví dụ của chúng tôi:

Hướng dẫn is python slow compared to c? - python có chậm so với c không?

Chúng tôi chỉ cần thêm một, phải không?

Những gì thực sự xảy ra dưới các bìa để thực hiện điều này trong Python, ngay cả sau khi nó đã được chuyển đổi thành mã byte, là (theo hồ sơ của tôi) 378 Hướng dẫn máy được thực hiện bởi máy ảo Python.

Làm điều tương tự trong C:

Hướng dẫn is python slow compared to c? - python có chậm so với c không?

Chi phí 1 Hướng dẫn máy, vì C biên soạn điều đó xuống ngôn ngữ lắp ráp và ngôn ngữ lắp ráp đó trông như thế này:

Hướng dẫn is python slow compared to c? - python có chậm so với c không?

Vì vậy, cuối cùng bạn làm rất nhiều công việc để hoàn thành một cái gì đó, khi chỉ một công việc nhỏ sẽ làm công việc.

Tại sao bản thân Python thực chất chậm trên đầu.

CPython là triển khai C của Python, đây là triển khai Python mặc định được sử dụng thực tế ở mọi nơi.

Thông dịch viên CPYThon không thể tận dụng lợi thế đáng kể của đa luồng.

Tại sao điều này?

Cpython có những gì mà người gọi là khóa phiên dịch toàn cầu. Điều này được người phiên dịch sử dụng để đảm bảo rằng chỉ có một luồng thực thi mã Python byte mỗi lần. Nếu một luồng gọi vào một mô -đun bên ngoài hoặc nó chặn, thì một luồng Python khác có thể chạy.

Bạn có thể có 5.000 lõi trong máy của mình, nhưng bạn sẽ chỉ chạy Python trên một trong số chúng tại một thời điểm.

Các mô -đun bên ngoài được viết trong một cái gì đó khác ngoài Python có thể cung cấp các cải tiến hiệu suất đáng kể, bởi vì chúng có thể sử dụng đa luồng này - đây được gọi là luồng mô hình căn hộ, và nó đã được phát minh bởi Microsoft vào năm 1996 hoặc là một phần của khung Viper của họ, đó là Cách thêm hỗ trợ đa luồng trong NT 3.51.

Khi luồng Cpython đi vào căn hộ của người dùng .

Giống như một con người vào căn hộ của riêng họ: nó có thể tháo quần áo (khóa) và nhảy xung quanh trần truồng, nếu nó muốn.

Làm cho Python nhanh hơn.

Java có một công nghệ gọi là JIT, hoặc chỉ trong biên dịch thời gian. Những gì một JIT làm là lấy mã byte và chuyển đổi nó thành ngôn ngữ lắp ráp gốc cho nền tảng mà nó chạy trên.

Một tên khác cho công nghệ này là tổng hợp động.

Những gì một JIT làm là làm các phần còn thiếu giữa mã byte và mã lắp ráp; Nó chuyển đổi mã byte thành mã lắp ráp, và sau đó lưu trữ lại để thực hiện lại.

Một JIT có thể gần như một chương trình được biên dịch tự nhiên, nhưng có thời gian chạy trên đầu để chuyển đổi, mỗi khi bạn chạy nó. Nó có một chi phí gia tăng, kết quả là mã không nhanh như nó có thể.

Để chống lại điều này, có lẽ bạn muốn biên dịch Java với mã gốc; Có một sản phẩm thương mại, được gọi là Excelsior Jet, mà bạn có thể mua để làm điều này. Ngoài ra còn có GCJ cũ (trình biên dịch GNU cho Java), đã bị xóa. Bạn có thể tìm thấy nó trong Lưu trữ, nhưng phiên bản sẽ không hỗ trợ hầu hết các phiên bản gần đây của Java. Nó đã bị ngừng sau khi thay đổi giấy phép Oracle, trên cơ sở triết học GNU.

Nhưng trở lại Python!

Có Jits cho Python không?

Chắc chắn rồi! Có Pypy, có Numba Numba và Microsoft có Pyjion (liên kết là các nguồn GitHub). Có một vài người khác, có xu hướng ít được biết đến và do đó ít được sử dụng hoặc duy trì.

Dự án Numba thậm chí có thể biên dịch Python một cách tĩnh - hoặc một tập hợp con của rpython, bản thân nó là một tập hợp con của Python - với mã gốc.

Thật không may, khi bạn sử dụng Python, bạn có thể không sử dụng bất kỳ thứ nào trong số này và bạn có thể sử dụng việc triển khai Python tiêu chuẩn, thay vào đó là CPython.

Vì vậy, điểm mấu chốt?

Python chậm hơn vì nó là một ngôn ngữ được giải thích.

Câu hỏi này ban đầu xuất hiện trên Quora - nơi để đạt được và chia sẻ kiến ​​thức, trao quyền cho mọi người học hỏi từ người khác và hiểu rõ hơn về thế giới. Bạn có thể theo dõi Quora trên Twitter, Facebook và Google+. Thêm câu hỏi:

Python có chậm hơn C không?

Mã Python bên trong được giải thích trong thời gian chạy thay vì được biên dịch thành mã gốc do đó nó chậm hơn một chút. Chạy tập lệnh Python V/S chạy mã C/C ++: Python: Đầu tiên nó được biên dịch thành mã byte. Mã byte này sau đó được giải thích và thực thi bởi PVM (máy ảo Python).it is a bit slower. Running of Python script v/s running of C/C++ code: Python: First it is compiled into Byte Code. This Byte Code is then interpreted and executed by the PVM (Python Virtual Machine).

Tại sao C nhanh hơn nhiều so với Python?

C/C ++ tương đối nhanh so với Python vì khi bạn chạy tập lệnh Python, trình thông dịch của nó sẽ diễn giải dòng tập lệnh theo từng dòng và tạo đầu ra nhưng trong C, trình biên dịch trước tiên sẽ biên dịch nó và tạo ra đầu ra được tối ưu hóa đối với phần cứng.

Cái nào nhanh hơn C hoặc C ++ hoặc Python?

C ++ nhanh hơn Python vì nó được gõ tĩnh, dẫn đến việc biên dịch mã nhanh hơn.Python chậm hơn C ++, nó hỗ trợ gõ động và nó cũng sử dụng trình thông dịch, điều này làm cho quá trình biên dịch chậm hơn. because it is statically typed, which leads to a faster compilation of code. Python is slower than C++, it supports dynamic typing, and it also uses the interpreter, which makes the process of compilation slower.

Tại sao Python rất chậm?

Không giống như các ngôn ngữ lập trình phổ biến khác bao gồm C# hoặc Java, Python được gõ động và ngôn ngữ được giải thích.Nó chậm chủ yếu do tính chất năng động và tính linh hoạt của nó.primarily due to its dynamic nature and versatility.