Bác biết file .pyc sinh ra để làm gì không
Thực ra ý này đúng 100% nhé "
Trong khi đó thằng Python nó sẽ vừa dịch từng dòng vừa chạy luôn"
Mình biết một chút về python, xin giải thích vài ý các bạn ở đây hiểu sai về interpreter language (python, Javascript) và Virtual Machine.
1/ Để viết code Python chúng ta cần gì?
Python Virtual Machine (PVM) + file text python (thường là file.py)
2/ Python chạy như thế nào?
Khi viết code Python sẽ có 2 cases:
Trường hợp một là file code chỉ chứa code thông thường, không có import module.
VD: file code.py chứa 1 dòng print("hello world")
Khi đó thì python mỗi lần chạy sẽ phải biên dịch dòng print("hello world") ra byte code (một ngôn ngữ trung gian mức thấp để interpreter đọc).
Vậy việc biên dịch code python này diễn ra như thế nào và có phải do interpreter đảm nhiệm như chúng ta hay nhầm tưởng không? Câu trả lời là không, vì interpreter dịch là là trình thông dịch, đúng với cái tên thì nó không thể đảm nhiệm việc biên dịch code python được, nhiệm vụ của nó là đọc mã byte code để thông dịch qua mã máy để thực thi. Python Virtual Machine gồm có 2 thành phần chính là compiler và interpreter. Compiler thì thường sẽ viết bằng C/C++ còn interpreter có thể viết bằng C (Cpython), Python (PyPy), Java (JPython) đây là cái chúng ta hay nhầm với python compiler. Vì thế việc biên dịch code python ra byte code là do một python compiler (py_compile) đảm nhiệm. Sau đó interpreter mới bắt đầu đọc byte code đã được compiled này để in ra dòng "hello world".
Trường hợp thứ 2 là file python ngoài chứa code thông thường còn có import thêm các module bên ngoài vào.
VD: ta có file code.py và một file module khác là printapi.py cần được import vào trong file code.py. File code.py có nội dung như sau:
import printapi
printapi.PrintHelloWorld()
Khi đó PVM khi gặp dòng import printapi việc đầu tiên sẽ kiểm tra xem file printapi.py có tồn tại trong PATH của python không, nếu có thì nó vào trong folder
pycache để tìm file printapi.pyc nếu file tồn tại thì nó sẽ kiểm tra xem cache byte code trong file printapi.pyc và mã code trong file printapi.py có khớp không. Nếu khớp thì PVM sẽ load data cache từ printapi.pyc vào trong file code.py. Nếu như cache byte code trong file printapi.pyc và mã code trong file printapi.py không khớp hoặc trong trường hợp không tìm thấy folder
pycache, PVM sẽ tạo ra folder tại đường dẫn chứa file code.py sau đó dùng compiler để biên dịch file printapi.py đồng thời tạo ra file printapi.pyc để chứa pycache byte code. Cuối cùng nó sẽ load pycache của module printapi vào file code.py. Thế trong trường hợp nếu PVM không tìm thấy file printapi.py thì sao? Không sao cả, vì quá trình import module chỉ cần file .pyc là đủ. Nếu không tìm thấy cả file printapi.pyc lẫn file printapi.py thì PVM sẽ báo lỗi "importError".
Việc sinh ra file pycache byte code .pyc này là một optimize trick để khi chạy lại lần sau nếu file module python cần import không thay đổi gì thì PVM sẽ bỏ qua bước biên dịch ra byte code mà sẽ dùng thằng interpreter để đọc mã byte code từ file .pyc để chuyển sang machine code luôn.
3/ Tại sao python hay những ngôn ngữ thuộc loại interpreter lại chậm hơn?
Nếu ta dịch nghĩa 2 từ interpreter và compiler ra sẽ là thông dịch và biên dịch.
Lấy một VD thế này, bạn interpreter với một người nước ngoài thì nếu bạn giao tiếp qua một thông dịch viên từng câu chắc chắn sẽ chậm hơn việc bạn đọc bản dịch toàn bộ những gì họ nói. Vì quá trình thông dịch (interpreter) sẽ cần phải xử lý linh động ngay tại chỗ (run time-dynamic). Cũng giống như python (javascript) khi chạy code thì phải dịch từng dòng code sang mã máy (quá trình thông dịch này bao gồm rất nhiều bước parser, dynamic type check,...) nên sẽ làm giảm tốc độc thực thi rất nhiều so với việc chạy trực tiếp từ mã máy các ngôn ngữ thuần biên dịch như C/C++/Fortran. Nhưng chính vì lý do này mà đổi lại python rất linh động, và dễ chỉnh sửa code nhanh. Chưa kể do việc thực thi thông qua PVM nên python sẽ không bị phụ thuộc vào kiến trúc hardware , dễ port qua lại giữa các nền tảng vì nếu PVM được viết đa nền tảng thì chắc chắn python cũng sẽ thừa hưởng đa nền tảng.
Nên để trả lời cho câu "file .pyc sinh ra để làm gì?" thì file .pyc chỉ là file cache chưa byte code để optimize tốc độ thực thi (bỏ qua được bước compiling). Và đặc biệt chỉ có ích cho trường hợp import module.
