C chậm hơn bao nhiêu so với C++?

Tại sao python chậm hơn C?

Câu trả lời của Terry Lambert, Nhóm nhân hệ điều hành Apple Core;

Quảng cáo

Python chậm hơn C vì nó là ngôn ngữ thông dị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 nó nhỏ hơn một giá trị nhất định, lớn hơn một giá trị nhất định hay chính xác bằng một giá trị nhất định, chẳng hạn như trong

C chậm hơn bao nhiêu so với C++?

Trong hợp ngữ, bạn cũng có thể thực hiện tương tự vòng lặp này

C chậm hơn bao nhiêu so với C++?

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 tạo ra 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 chạy trong máy ảo

(Tôi nói “gần như” bởi vì nó không nhất thiết phải như vậy, nhưng ngoại trừ trong những trường hợp thực sự hạn chế - không, thực ra, nó thực sự phải như vậy)

Quảng cáo

Một tên gọi khác của máy ảo là “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 lệnh được giải thích hơn là thực hiện một lệnh máy thực tế

thời gian ví dụ. vâng

Ví dụ, hãy lấy x += 1. Trong CPU Intel, số gia của một thanh ghi là một thao tác đơn lẻ, có độ trễ là 1 và giá trị thông lượng đối ứng là 1/3

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

Làm thế nào điều này x += 1 được thực hiện trong Python?

Để biết điều này, bạn phải biết cách Python hoạt động bên trong

Bên trong, Python bao gồm một bộ mã thông báo, bộ phân tích từ vựng, bộ tạo mã byte và trình thông dịch mã byte

  • Tokenizer Công cụ 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
  • Trình 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 khoảng trống và thụt đầu dòng có ý nghĩa đó. Đây là nơi kiểm tra cú pháp xảy ra
  • Trình tạo mã byte Đây là một phần của Python thực hiện tối ưu hóa, nếu có;
  • Trình thông dịch mã byte Đâ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

Mã byte, sau khi được tạo thường được lưu vào bộ nhớ cache

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

Quảng cáo

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

Điều này là nhanh chóng, 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 sẽ nhanh hơn, nhưng điều này không giống như hoạt động nhanh như mã máy

Máy ảo không phải là CPU thực mà mã đang chạy trên đó

Giới thiệu ngắn về máy ảo

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

Ngay sau đó, Microsoft đã phát hành phiên bản BASIC của họ (dựa trên BASIC của Đại học Dartmouth từ năm 1964), phiên bản này đã mã hóa mã BASIC giống như cách mã hóa Python ngày nay. BASIC được lưu trữ trong bộ nhớ giống như cách mã byte của Python được lưu trữ trong bộ nhớ sau khi mã hóa, mặc dù BASIC trì hoã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 BASIC

Ngoà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 câu lệnh, thay vì không có số dòng và sử dụng GOTO thay vào đó, Python phần lớn giống với trình thông dịch BASIC mà chúng ta đã có 40 năm trước

Quảng cáo

"Biên dịch" vs. biên soạn

UCSD Pascal đã biên dịch không được biên dịch sang hợp ngữ, giống như các ngôn ngữ biên dịch khác vào thời điểm đó

Thay vào đó, nó được biên dịch thành p-Code

Apple, nơi tôi làm việc, có giấy phép duy nhất không thể thu hồi đối với hệ thống UCSD p-Code. Đây là một lỗi cấp phép mà UCSD sau đó đã không lặp lại

Hầu hết ProDOS trên Apple II được viết bằng Pascal và hầu như tất cả mã để thực hiện QuickDraw trong Macintosh đời đầu đều được viết bằng Pascal

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

Python cũng có khái niệm “Python biên dịch”;

Quảng cáo

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

Khi bạn nhìn thấy một tập tin kết thúc bằng. pyc, đây là “PYthon, đã biên dịch”

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

Mã nguồn

Một chương trình không thực sự là mã gốc cho đến khi nó được biên dịch và một chương trình chưa thực sự được biên dịch thành mã gốc cho đến khi nó được biên dịch thành 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ã hợp ngữ thay vì mã byte, chuyển mã hợp ngữ tới trình biên dịch mã hợp ngữ và trình biên dịch mã nhổ 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ó được liên kết với thời gian chạy nền tảng. Bộ thực thi thiết lập môi trường mà mã sẽ chạy trong đó và có thể cung cấp một số dịch vụ thời gian thực, chẳng hạn như tải đối tượng động. Biên dịch C có thời gian chạy. C++ đã biên dịch có thời gian chạy

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

Quảng cáo

Quá trình liên kế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 tệp thực thi độc lập được gọi là "liên kết"

Máy ảo không thực hiện liên kết; . Mặc dù bản thân 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 để tăng tốc hoạt động trong Python và là cơ sở của JNI (Giao diện gốc Java) — các mô-đun này thường được viết bằng ngôn ngữ được biên dịch, chẳng hạn

Sau đó, một cái gì đó không được biên dịch, trừ khi nó trở thành tệp nhị phân riêng cho nền tảng mà nó đang chạy trên đó

Tại sao chạy trong máy ảo khiến bạn chậm

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

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

C chậm hơn bao nhiêu so với C++?

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

Điều thực sự xảy ra dưới vỏ bọc để triển khai đ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 thi bởi máy ảo Python

Quảng cáo

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

C chậm hơn bao nhiêu so với C++?

tốn 1 lệnh máy, bởi vì C biên dịch nó thành ngôn ngữ hợp ngữ và ngôn ngữ hợp ngữ đó trông như thế này

C chậm hơn bao nhiêu so với C++?

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

Tại sao bản thân Python lại chậm về bản chất

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

Trình thông dịch CPython không thể tận dụng lợi thế đáng kể của đa luồng

Tại sao lại thế này?

CPython có cái được gọi là khóa trình thông dịch toàn cầu. Điều này được trình thông dịch sử dụng để đảm bảo rằng chỉ có một luồng thực thi mã byte Python tại một thời điểm. 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

Quảng cáo

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 bằng thứ gì đó không phải Python có thể mang lại những cải tiến đáng kể về hiệu suất, bởi vì chúng có thể sử dụng đa luồng này - đây được gọi là Phân luồng mô hình căn hộ và được Microsoft “phát minh” vào năm 1996 hoặc lâu hơn như một phần của khung ViPER của họ. . 51

Sau khi luồng CPython đi vào “Căn hộ” (mô-đun), nó sẽ bỏ khóa trình thông dịch toàn cục và có thể sử dụng nhiều luồng trong mã C/C++/mã khác mà nó muốn — cho đến khi nó quay trở lại căn hộ

Giống như một con người bước vào căn hộ của chính họ. nó có thể cởi bỏ quần áo (khóa) và nhảy múa khỏa thân, nếu nó muốn

Làm Python nhanh hơn

Java có một công nghệ gọi là JIT, hoặc biên dịch Just In Time. Những gì một JIT làm là lấy mã byte và chuyển đổi nó thành ngôn ngữ hợp ngữ gốc cho nền tảng mà nó đang chạy trên đó

Quảng cáo

Một tên gọi khác của công nghệ này là biên dịch động

Những gì một JIT làm là thực hiện các phần còn thiếu giữa mã byte và mã hợp ngữ;

Một JIT có thể nhanh gần bằng một chương trình được biên dịch nguyên gốc, nhưng có chi phí thời gian chạy cho quá trình chuyển đổi, mỗi khi bạn chạy nó. Đó là một chi phí gia tăng, dẫn đến mã không nhanh như nó có thể

Để chống lại điều này, bạn có thể muốn biên dịch Java thành mã gốc; . 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 kho lưu trữ, nhưng phiên bản này sẽ không hỗ trợ hầu hết các phiên bản Java mới nhất. Nó đã bị ngừng sau khi thay đổi giấy phép của Oracle, trên cơ sở triết học GNU

Nhưng quay lại với Python

Có JIT cho Python không?

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

Dự án Numba thậm chí có thể biên dịch tĩnh Python — 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 — thành mã gốc

Quảng cáo

Thật không may, khi bạn sử dụng Python, có thể bạn không sử dụng bất kỳ thứ nào trong số này và có thể bạn đang sử dụng 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à 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 thu thập và chia sẻ kiến ​​thức, trao quyền cho mọi người học hỏi từ những 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

C chậm hơn bao nhiêu so với C++?

Hyperfine cho tôi biết rằng chương trình C++ dựa trên thư viện C++ được tải động mất gần 1 ms thời gian hơn chương trình C.

C có chạy nhanh hơn C++ không?

Hiệu suất dựa trên Bản chất của ngôn ngữ . Vì nó hỗ trợ hướng đối tượng nên tốc độ nhanh hơn so với ngôn ngữ C .

C Sharp có nhanh hơn C không?

Do đó, các tệp nhị phân C# lớn hơn nhiều sau khi biên dịch so với C++. Hiệu suất. C ++ được sử dụng rộng rãi khi các ngôn ngữ cấp cao hơn không hiệu quả. Mã C++ nhanh hơn nhiều so với mã C#, điều này khiến nó trở thành giải pháp tốt hơn cho các ứng dụng quan trọng về hiệu suất

C nhanh hơn bao nhiêu so với CPP?

Mã giống nhau trong C và C++ thường chạy ở tốc độ chính xác như nhau , ngoại trừ mã có ngữ nghĩa khác nhau do quy tắc răng cưa khác nhau, v.v. Sự khác biệt giữa thành ngữ C và thành ngữ C++.