Tôi có thể chuyển đổi mã Python của mình sang C không?

Python là một ngôn ngữ hiện đại vay mượn các khái niệm lập trình nâng cao từ một số ngôn ngữ khác như C++, Java, Lisp và Haskell. Sẽ rất khó để diễn đạt những điều này trong C. Cho đến nay, không có công cụ hoàn hảo để làm điều này. Bạn cần sắp xếp lại mã và hiểu nó

[quảng cáo_1]

chuyển mã python sang c trực tuyến miễn phí

a=[int(x) for x in input().split()] 
n=int(input()) 
l=[] 
for i in range(len(a)-1):
    c=0 
    print(a[i],a[i+1]) 
    for j in range(2, min(a[i], a[i+1])+1):
        if a[i]%j==a[i+1]%j==0:
            c=1 
    if c==0 and a[i]>a[i+1]:
        l.append(i)
print(l[0])

chuyển mã python sang c trực tuyến miễn phí

name=input("please enter your name: ")
print("your name is " + name)
print("name data type: ",type(name))

age = input("please enter your age: ")
print("your age is " + age)
print("name data type: ",type(age))

chuyển mã python sang c trực tuyến miễn phí

n=int(input())
a,b=map(int,input().split())
for j in range(n):
x=int(input())
c=0
for i in range (a,b+1):
if(x%i==0):
c+=1
print(c)

chuyển mã python sang c trực tuyến miễn phí

while true :
	tempExt = temperatureExterieure()
	tempInt = temperatureInterieure()
	if tempInt < 18 :
		radiateur.run()
	else :
		radiateur.sleep()

[quảng cáo_2]

Tôi có thể chuyển đổi mã Python của mình sang C không?

Hãy chia sẻ

Chương trình Python không cần thiết đầu tiên của tôi là một chương trình 1400 dòng đã xây dựng và thao tác với các biểu đồ lớn. Mặc dù tôi thấy Python được tạo ra để phát triển rất nhanh, nhưng kết quả hơi đáng thất vọng - các đầu vào cỡ trung bình có thể mất nhiều ngày để chạy, khiến cho các đầu vào lớn trở nên bất khả thi

Tôi đã áp dụng các kỹ thuật tối ưu hóa thông thường []. Sử dụng trình hồ sơ của Python, tôi có thể xác định ``điểm nóng'' trong chương trình mà phần lớn thời gian đã được sử dụng; . Việc thực hiện các phép biến đổi theo cách thủ công chẳng hạn như di chuyển mã bất biến ra khỏi vòng lặp đã giúp ích ở mức độ thấp hơn. Kết quả của việc tối ưu hóa này là một chương trình Python hiện mất vài giờ cho các đầu vào mà trước đây mất vài ngày. Một cải tiến tốt, nhưng vẫn chưa đủ nhanh

Tại thời điểm này, tôi đã chạm phải rào cản tối ưu hóa. Truyền thuyết Python thông thường quy định rằng tôi nên mã hóa lại các điểm nóng thành C, một số hạn chế về thời gian đã ngăn cản. Ngoài ra, tôi muốn tránh các vấn đề về bảo trì và tính di động do mã nguồn lai tạo ra. Điều tôi muốn là một công cụ tự động chuyển đổi các bit mã Python được thực thi thường xuyên nhất của tôi thành C

Trong nội bộ, Python không diễn giải trực tiếp các chương trình Python. Thay vào đó, nó có một trình biên dịch dịch các chương trình Python thành mã cho một máy tính trừu tượng được lý tưởng hóa - Máy ảo Python (PVM). Sau đó, trình thông dịch Python sẽ thực thi mã PVM (Hình ). Bản thân PVM là một ``máy xếp chồng'', nghĩa là các lệnh PVM lấy các đối số của chúng từ ngăn xếp và đặt kết quả của chúng vào ngăn xếp

Tôi có thể chuyển đổi mã Python của mình sang C không?

Hình 1. Thực thi các chương trình Python

Máy ảo và ngăn xếp không phải là mới. Ý tưởng này đã có từ nhiều thập kỷ, nhưng đã hết thịnh hành vào cuối những năm 1970 []. Gần đây, nó đã được phục hưng với sự ra đời của Java, sử dụng máy ảo

Tin tốt là có rất nhiều nghiên cứu đề cập đến việc vận hành hiệu quả các máy này. Đặc biệt, công việc đã được thực hiện để tăng tốc Forth [,], Smalltalk [,] và tất nhiên là Java []. Họ đã thành công lớn trong việc triển khai ngôn ngữ nhanh hơn và rất nhiều tài liệu này có thể được áp dụng để tăng tốc Python

Phần còn lại của bài viết này được chia thành hai phần. Phần  mô tả công việc của tôi trên 211, một chương trình thử nghiệm chuyển đổi mã PVM thành C. Trong Phần  tôi đề xuất một số thay đổi đối với hoạt động bên trong của Python mà tôi cho rằng sẽ giúp nó dễ dàng hơn trong việc tối ưu hóa và triển khai tốc độ cao

2  Chương trình 211

Chương trình 211 của tôi lấy cảm hứng từ chương trình Toba dành cho Java, mà các tác giả gọi nó là ``trình biên dịch đi trước thời đại'' []. Ý tưởng là một ứng dụng Python được định hình và có mã PVM cho các điểm nóng của nó được chuyển đổi thành mã C vào năm 211. Trình thông dịch Python được biên dịch lại với đầu ra mã C của 211, tạo ra một trình thông dịch Python tùy chỉnh mà ứng dụng Python có thể sử dụng (Hình )

Tôi có thể chuyển đổi mã Python của mình sang C không?

Hình 2. Một mô hình của 211

Bởi vì nó hoạt động ở cấp độ PVM, 211 có thể cùng tồn tại với bất kỳ trình tối ưu hóa PVM cấp cao nào. Điều này bao gồm các trình tối ưu hóa PVM bổ sung các mã lệnh mới - 211 chỉ chuyển đổi các mã lệnh PVM mà nó đã được dạy, vì vậy đầu ra mã PVM của 211 có thể là sự kết hợp của các lệnh VM thông thường và lệnh gọi tới mã C chuyên dụng

Chỉ cần thêm một dòng vào mã trình thông dịch Python để 211 hoạt động. một câu lệnh #incoide để bao gồm đầu ra mã C của 211

Bản thân 211 bao gồm 1320 dòng mã Python, khoảng 635 dòng trong số đó là các bit mã trình thông dịch của Python mà 211 sử dụng để chuyển đổi. Chương trình dựa trên Python 1. 5. 1

Để hiểu cách tôi chuyển đổi mã PVM sang mã C, trước tiên hãy xem trình thông dịch Python

2. 1  Trình thông dịch Python

Trình thông dịch Python đôi khi được gọi là trình thông dịch ``cổ điển'' []. Thuật toán của nó rất đơn giản

  1. Tìm nạp opcode của lệnh VM và các đối số của nó (nếu có)
  2. Thực hiện hướng dẫn
  3. Lặp lại các bước 1 và 2 cho đến khi tính mới biến mất

Thuật toán này được triển khai trong trình thông dịch Python bằng mã C như được hiển thị bên dưới (được đơn giản hóa rất nhiều so với bản gốc)

while (1) {
    opcode = NEXTOP();
    if (HAS_ARG(opcode))
        oparg = NEXTARG();

    switch (opcode) {
    ...
    }
}

Các trường hợp trong câu lệnh chuyển đổi thực hiện các hướng dẫn VM khác nhau. Như đã thảo luận trong phần tiếp theo, 211 chuyên biệt hóa trình thông dịch Python bằng cách thêm mã vào câu lệnh chuyển đổi này

2. 2  Điều 211 làm

211 có bốn bước cơ bản

  1. đọc trong một. pyc và giải nén mã PVM
  2. Chia mã PVM thành các khối cơ bản mở rộng. Khối cơ bản mở rộng (EBB) là chuỗi hướng dẫn dài nhất chỉ có một điểm vào (tuy nhiên, có thể có nhiều lối thoát khỏi một EBB) []. Mã giả thuyết trong Hình chứa hai EBB

    Tại sao sử dụng EBB? . Thay vì sửa đổi rộng rãi trình thông dịch, tôi đã chọn sử dụng EBB, điều này đảm bảo rằng tất cả các mục tiêu nhánh tương ứng với mã PVM chứ không phải mã C

    Hình 3. Khối cơ bản mở rộng
  3. Chuyển đổi các hướng dẫn PVM trong mỗi EBB thành mã C, tạo một mã opcode PVM mới cho mỗi EBB một cách hiệu quả. Chuyển đổi của 211 là vấn đề dán mã từ câu lệnh chuyển đổi chính của trình thông dịch Python. Ví dụ: một EBB chứa ba lệnh PVM sẽ được chuyển đổi thành mã cho lệnh #1 mã cho lệnh #2 mã cho lệnh #3

    For the most part, the code from the Python interpreter is used with very little modification. In a few important cases, however, 211 will customize the C code to produce better output. In effect, 211 performs a limited amount of partial evaluation []. One example is the conversion of branches in the PVM code to goto statements wherever possible. Another example involves the PVM comparison instruction - usually, the Python interpreter decides at run-time what type of comparison (e.g., <, >=) to perform, but 211 can determine this at compile time.

  4. Viết lại mã PVM trong. pyc để nó sử dụng opcodes mới
Hãy xem xét các chức năng dưới đây. Rõ ràng đây là một ví dụ giả tạo, nhưng nó minh họa độc đáo hoạt động của 211.
def foo():
    pass

Mã PVM cho chức năng này được hiển thị bên dưới, được phân tách bởi dis. dis(foo). (Nhớ lại rằng các hàm không có câu lệnh trả về rõ ràng sẽ trả về giá trị Không có. )

0  SET_LINENO       1
3  SET_LINENO       2
6  LOAD_CONST       0  (None)
9  RETURN_VALUE

Khi được thực thi bởi PVM, hai hướng dẫn PVM đầu tiên lưu trữ số dòng nguồn từ mã Python ban đầu, để sử dụng trong truy nguyên. Lệnh thứ ba đẩy hằng số 0 của hàm, Không có, vào ngăn xếp của PVM. Cuối cùng, lệnh thứ tư lấy giá trị ra khỏi ngăn xếp và trả về

Bên trong trình thông dịch Python, mã này sẽ được triển khai

while (1) {
    opcode = NEXTOP();
    if (HAS_ARG(opcode))
        oparg = NEXTARG();

    switch (opcode) {
    ...
    case RETURN_VALUE:
        retval = POP();
        why = WHY_RETURN;
        break;
    case LOAD_CONST:
        x = GETCONST(oparg);
        Py_INCREF(x);
        PUSH(x);
        break;
    case SET_LINENO:
        f->f_lineno = oparg;
        break;
    ...
    }
}

Chương trình 211 của tôi lấy tất cả bốn hướng dẫn PVM và viết lại chúng thành một hướng dẫn duy nhất 211_OPCODE 0. Sau đó, nó xuất ra mã C bên dưới, mã này được # đưa vào câu lệnh chuyển đổi chính của trình thông dịch Python

________số 8_______

211 sau đó xem qua mã C mà nó xuất ra và thực hiện ``tối ưu hóa lỗ nhìn trộm'' - nói cách khác, nó tìm kiếm mã không hiệu quả hoặc dư thừa và thay thế bằng mã cải tiến []. Điều này không có nghĩa là mã của trình thông dịch Python không hiệu quả hoặc dư thừa ngay từ đầu; . Mã C kết quả được hiển thị bên dưới

    case 211:
        switch (oparg) {
        case 0:
            f->f_lineno = 2;
            
            x = GETCONST(0);
            Py_INCREF(x);
            
            retval = x;
            why = WHY_RETURN;
            break;
        }
        break;

Trong ví dụ này, trình tối ưu hóa lỗ nhìn trộm của 211 có thể loại bỏ các thao tác PUSH/POP liền kề và xóa phép gán không cần thiết cho f_lineno. Các mẫu này được phát hiện trong mã C bằng một số biểu thức chính quy đơn giản

Trình thông dịch Python được biên dịch lại tiếp theo, kết hợp đầu ra mã C của 211. Mã PVM được viết lại (một lệnh) cho foo() hiện có thể chạy được và nó sẽ sử dụng mã thông dịch tùy chỉnh mới

2. 3  Điều 211 không làm

Khi một loạt các hướng dẫn PVM đã được thay thế bằng mã C chuyên biệt của 211, vòng lặp thông dịch không được thực thi bởi mã C trừ khi cần thiết. Việc tăng tốc độ mà 211 đạt được một phần là do tránh chi phí vòng lặp này

Thật không may, vòng lặp trình thông dịch Python chứa mã để xử lý các tác vụ định kỳ, chẳng hạn như kiểm tra tín hiệu và thay đổi trạng thái luồng. Bằng cách thực hiện vòng lặp trình thông dịch ít thường xuyên hơn, các chương trình được chuyển đổi sang C sử dụng 211 sẽ ít phản hồi hơn với những sự kiện này

Một điều khác cần lưu ý là 211 chỉ giải quyết một lĩnh vực hiệu suất của Python. Nếu một chương trình Python dành phần lớn thời gian của nó trong thư viện thời gian chạy hoặc bị ràng buộc I/O, thì việc chuyển đổi nó thành C sẽ không có tác động lớn

2. 4  Kết quả

Kết quả ban đầu của 211 tốt nhất có thể được mô tả là `` hỗn hợp. '' Tất cả các kết quả trong phần này được tạo trên một máy có bộ xử lý Pentium-MMX 200MHz, 512K bộ nhớ cache và 64M RAM, sử dụng Windows NT 4. 0 và Visual C++ 5. 0. Phiên bản 211 đã sử dụng chuyển đổi ít hơn một nửa hướng dẫn PVM. nó có thể chuyển đổi 37 trong tổng số 84 hướng dẫn PVM

Bảng  hiển thị kết quả cho Pystone 1. 1, điểm chuẩn Dhrystone có trong bản phân phối Python. Tôi đã chạy ba bài kiểm tra. một trình thông dịch Python chưa sửa đổi trực tiếp từ bản phân phối Win32; . pyc; . pyc. các tập tin ceval. c là tệp nguồn C chứa trình thông dịch Python

UnmodifiedModified211Results (Pystones/giây)2736. 422708. 752921. 17ceval. c (dòng)29161489014890ceval. obj (byte)49838116540116540pystone. pyc (byte)827082706018Bảng 1. Kết quả Pystone (biên dịch đầy đủ sang C)

Từ những con số, có thể nói rằng 211 tăng tốc mã Pystone, nhưng với chi phí quá cao để chứng minh. Mặt khác, bộ điểm chuẩn PyBench [] cho thấy một số điểm thú vị hơn (và đầy hứa hẹn. ) kết quả trong Hình

Pybench được chuyển đổi thành C là quá nhiều để Visual C++ trên máy của tôi tối ưu hóa, vì vậy thay vào đó tôi đã chọn một trong các tệp nguồn của nó, Constructs. py và chạy nó qua 211 một mình. Điều này có nghĩa là các bài kiểm tra ``If Then Else,'' ``Nested For Loops'' và ``For Loops'' đã được biên dịch thành C - điều này có thể được coi là chọn một điểm nóng trong chương trình Python và chuyển đổi nó . Điều này dẫn đến 17000 dòng được thêm vào ceval. c và kích thước tệp đối tượng là 137383 byte

Ba bài kiểm tra bị ảnh hưởng trực tiếp bởi 211 cho thấy sự cải thiện tốc độ đáng kể. Tôi phỏng đoán rằng tốc độ giảm nhẹ khi sử dụng mã PVM chưa được chuyển đổi và trình thông dịch đã sửa đổi có liên quan đến kiến ​​trúc. ceval. obj vượt qua ngưỡng kích thước bắt buộc phải sử dụng các lệnh rẽ nhánh chậm hơn trong mã máy Pentium. Tuy nhiên, có một số giả tạo - kết quả cho ``BuiltinMethodLookup'' và ``StringSlicing'' - cần nghiên cứu thêm

Câu hỏi tiếp theo là kỹ thuật chuyển đổi này có thể được đẩy đi bao xa?

PYBENCH 0.6

Benchmark: 211-python (rounds=10, warp=20)

Tests:                              per run    per oper.  diff *
------------------------------------------------------------------------
          BuiltinFunctionCalls:     791.87 ms    6.21 us   +2.35%
           BuiltinMethodLookup:     944.35 ms    1.80 us   +8.73%
                 ConcatStrings:    2297.37 ms   15.32 us   -0.39%
               CreateInstances:    1198.43 ms   28.53 us   -2.26%
       CreateStringsWithConcat:     889.78 ms    4.45 us   -0.77%
                  DictCreation:    1161.54 ms    7.74 us   -0.18%
                      ForLoops:     523.39 ms   52.34 us  -62.11%
                    IfThenElse:     684.27 ms    1.01 us  -38.49%
                   ListSlicing:    1006.17 ms  287.48 us   +2.18%
                NestedForLoops:     383.25 ms    1.10 us  -49.84%
          NormalClassAttribute:     957.16 ms    1.60 us   +0.35%
       NormalInstanceAttribute:     931.60 ms    1.55 us   +0.38%
           PythonFunctionCalls:     890.95 ms    5.40 us   +3.89%
             PythonMethodCalls:     725.18 ms    9.67 us   -0.02%
                     Recursion:     690.87 ms   55.27 us   +2.17%
                  SecondImport:     937.91 ms   37.52 us   -4.78%
           SecondPackageImport:     961.25 ms   38.45 us   -5.25%
         SecondSubmoduleImport:    1174.28 ms   46.97 us   -4.81%
       SimpleComplexArithmetic:    1150.36 ms    5.23 us   -1.00%
        SimpleDictManipulation:     842.63 ms    2.81 us   -0.08%
         SimpleFloatArithmetic:     814.21 ms    1.48 us   +0.01%
      SimpleIntFloatArithmetic:     855.92 ms    1.30 us   +0.71%
       SimpleIntegerArithmetic:     857.16 ms    1.30 us   +0.72%
        SimpleListManipulation:    1033.49 ms    3.83 us   +3.93%
          SimpleLongArithmetic:     929.77 ms    5.63 us   +0.11%
                    SmallLists:    1569.67 ms    6.16 us   +3.16%
                   SmallTuples:     950.77 ms    3.96 us   +2.78%
         SpecialClassAttribute:     962.20 ms    1.60 us   +0.14%
      SpecialInstanceAttribute:    1062.08 ms    1.77 us   -0.54%
                 StringSlicing:     949.31 ms    5.42 us  -11.92%
                     TryExcept:    1658.73 ms    1.11 us   +2.33%
                TryRaiseExcept:     990.82 ms   66.05 us   -3.89%
                  TupleSlicing:     903.79 ms    8.61 us   -5.57%
------------------------------------------------------------------------
            Average round time:   37401.40 ms              -4.80%

*) measured against: unmodified-python (rounds=10, warp=20)
Hình 4. Kết quả PyBench (biên dịch một phần sang C)

3  Làm thế nào để làm tốt hơn

Trong phần này, tôi thảo luận về năm cách mà tôi nghĩ nên (và trong một trường hợp là không nên) thực hiện để có kết quả tốt hơn khi chuyển đổi mã PVM sang C;

Những bình luận này không nên được hiểu là một lời chỉ trích về thiết kế hiện tại của Python. Tuy nhiên, một số thiết kế phù hợp với một số ứng dụng nhất định hơn những thiết kế khác, và có thể nói rằng các ứng dụng như 211 không phải là ưu tiên khi Python được tạo ra.

3. 1  Giáo dục Opcode

Trong Phần  tôi đã nói rằng 211 vẫn chưa thể chuyển đổi tất cả các opcode của PVM thành C. Không có khó khăn kỹ thuật nào ngăn cản việc dạy 211 về các mã còn lại. Để tiện lợi, tôi đã thêm mã opcode một cách lười biếng theo yêu cầu của đầu vào mã PVM cho 211

Khi chạy, 211 in ra danh sách ``mười mã hàng đầu'' của mã opcode PVM mà nó không thể chuyển đổi, được sắp xếp theo tần suất xuất hiện của chúng. Điều này đưa ra một dấu hiệu tĩnh về các mã lệnh để dạy 211; . Tôi đã sử dụng cả hai biện pháp này khi quyết định thực hiện opcodes nào

Điều này có nghĩa là, hiện tại, một bản viết lại. tệp pyc luôn chứa một số hướng dẫn PVM thông thường. Nếu những điều này xảy ra ở một vị trí quan trọng trong chương trình, chẳng hạn như vòng lặp bên trong, thì hiệu suất sẽ bị ảnh hưởng. Dạy 211 bộ mã PVM hoàn chỉnh sẽ loại bỏ sự chuyển đổi giữa mã chuyên dụng và không chuyên biệt, tránh được một nguồn chi phí chung. Các chuỗi mã C dài hơn cũng sẽ tạo ra nhiều cơ hội tối ưu hóa hơn, cho cả trình tối ưu hóa lỗ nhìn trộm của 211 cũng như cho trình tối ưu hóa của trình biên dịch C

3. 2  Trắc nghiệm chuyển đổi

Hiện tại, 211 luôn cố gắng chuyển đổi các chuỗi lệnh PVM dài nhất mà nó có thể. Đây có thể không phải là chiến lược tốt nhất, vì nó có thể dẫn đến hàng loạt mã C được xuất ra; . Một cách tiếp cận tốt hơn có thể là chuyển đổi có chọn lọc mã PVM, dựa trên kinh nghiệm hoặc ngưỡng. Chẳng hạn, chuyển đổi có thể bị hạn chế đối với các cặp hướng dẫn thường thấy

Lý tưởng nhất là các kinh nghiệm chuyển đổi có thể được điều chỉnh để 211 mang lại tốc độ tăng có thể chấp nhận được, nhưng với số lượng mã C nhỏ hơn nhiều so với đầu ra hiện tại. Không chắc rằng một phương pháp phỏng đoán duy nhất sẽ hoạt động tốt cho tất cả các đầu vào;

3. 3  Đăng ký máy

Như đã đề cập trong phần giới thiệu, PVM là một cỗ máy xếp chồng. Như vậy, có chi phí liên quan đến việc di chuyển các đối tượng đến và đi từ ngăn xếp. Một giải pháp thay thế là máy dựa trên thanh ghi, đặt các giá trị trung gian vào các thanh ghi thay vì trên ngăn xếp và không phát sinh chi phí ngăn xếp. Người ta nói rằng các chương trình chuyển đổi mã Forth và Java VM thành C bắt đầu bằng cách ánh xạ các vị trí ngăn xếp thành ``các thanh ghi'' bằng cách đặt các giá trị của chúng vào các biến C [,]. Để thực hiện điều này sẽ yêu cầu thay đổi PVM cũng như trình biên dịch Python

Có một lý do thuyết phục khác để xem xét VM dựa trên đăng ký. Có sẵn một số trình biên dịch C tối ưu hóa tốt, mặc dù đây là ngôn ngữ nổi tiếng khó tối ưu hóa. Về việc chuyển đổi PVM sang C, điều quan trọng là có được đầu ra C ở dạng sao cho trình biên dịch C tối ưu hóa có thể sử dụng tốt nó. Nhưng ngay cả những trình biên dịch C tốt nhất cũng không có khả năng phát hiện ra cách các giá trị trên ngăn xếp tương quan với nhau - các thao tác ngăn xếp xuất hiện giống như các thao tác con trỏ trên bộ nhớ. Bằng cách chuyển sang VM dựa trên thanh ghi, luồng dữ liệu qua mã C trở nên rõ ràng hơn (khi sử dụng các biến C) và trình biên dịch có cơ hội tốt hơn để thực hiện nhiều tối ưu hóa hơn

Chương trình C sau đây tóm tắt thao tác ngăn xếp trong trình thông dịch Python. Không gian cho ngăn xếp được phân bổ bên ngoài và các phần tử của ngăn xếp được tham chiếu bằng con trỏ

int i, j;

void interpreter(void) {
    extern int *get_frame(void);
    int *stack_pointer = get_frame();

    #define PUSH(x)  (*stack_pointer++ = x)
    #define POP()    (*--stack_pointer)

    PUSH(123);
    PUSH(456);
    i = POP();
    j = POP();
}

Ngay cả về lý thuyết, rất khó để trình biên dịch C tối ưu hóa xác định một thuộc tính khóa về các giá trị được đẩy lên ngăn xếp. sức sống của họ. Nói cách khác, nó không thể biết liệu một chức năng khác có muốn sử dụng nội dung của bộ nhớ được phân bổ cho ngăn xếp hay không, vì vậy nó phải ghi cả hai số vào bộ nhớ (trái ngược với việc chỉ giữ chúng trong sổ đăng ký). Trong thực tế, trình biên dịch C thậm chí còn tệ hơn. cả Visual C++ và gcc với tối ưu hóa hoàn toàn đều không thể phát hiện ra rằng j được cho là có giá trị 123 mà không cần tải lại từ bộ nhớ

Ngược lại, giả sử rằng chúng ta có một VM dựa trên thanh ghi. Một chương trình như 211 có thể ánh xạ tầm thường các thanh ghi thành các biến C, dẫn đến một chương trình như chương trình bên dưới

int i, j;

void interpreter(void) {
    int reg_0, reg_1;

    reg_0 = 123;
    reg_1 = 456;
    i = reg_1;
    j = reg_0;
}

Tính sống động của các giá trị và luồng dữ liệu hiện rõ ràng đối với trình biên dịch C. Cả hai trình biên dịch C đã đề cập ở trên đều thực hiện xuất sắc việc dịch chương trình này thành hợp ngữ

3. 4  Độ chi tiết của hướng dẫn

Một sự thất vọng khi phát triển 211 là rất nhiều thông tin đã bị chôn vùi bên trong mã C của trình thông dịch thay vì được làm rõ trong mã PVM; . Tôi đề xuất các hướng dẫn PVM chi tiết hơn, trong đó mỗi lệnh PVM hiện tại sẽ được thay thế bằng một hoặc nhiều lệnh ngắn hơn. Về bản chất, điều này sẽ tạo ra một PVM giống RISC hơn. Kết quả ngay lập tức của sự thay đổi này sẽ lớn hơn. pyc và thực thi chậm hơn do số lượng lệnh lớn hơn được gửi trong trình thông dịch. Tuy nhiên, về lâu dài, tôi nghĩ rằng khoản lỗ này sẽ được bù đắp nhiều hơn bằng cách tiết lộ nhiều thông tin hơn cho các chương trình loại 211 và trình tối ưu hóa PVM cấp cao

3. 5  Cấu trúc phiên dịch

Có các phương pháp khác được biết để thực hiện trình thông dịch. ``Mã luồng'' và ``mã luồng gián tiếp'' là hai kỹ thuật được sử dụng trong triển khai trình thông dịch [,]. Mặc dù các chi tiết của hai phương pháp này nằm ngoài phạm vi của bài báo này, nhưng có thể nói rằng cả hai đều loại bỏ vòng lặp tìm nạp-thực thi của các trình thông dịch cổ điển. Tuy nhiên, cả hai đều không có khả năng gây ra bất kỳ tác động nào đối với PVM hiện tại. Người ta đã chỉ ra rằng sự khác biệt về tốc độ giữa các phương pháp trở nên không tồn tại khi lượng thời gian thực hiện bởi mỗi lệnh VM tăng lên [];

Vì điều này, tôi nghĩ không đáng để thay đổi cấu trúc của trình thông dịch cho đến khi Python có PVM giống RISC hơn, với các hướng dẫn chi tiết hơn. Đối số này cũng có thể được mở rộng một cách hợp lý để ngăn cản ``tối ưu hóa vi mô'' trong mã tìm nạp lệnh PVM

4. Kết luận

Trong bài báo này, tôi đã mô tả 211, một chương trình thử nghiệm chuyển đổi mã máy ảo Python thành C. 211 được thiết kế để sử dụng trên các ứng dụng Python cần chạy nhanh hơn, trong đó việc dịch thủ công các điểm nóng sang C không phải là một tùy chọn khả thi. Kỹ thuật chuyển đổi chung đã cho thấy giá trị, cả trong kết quả của riêng tôi và trong công việc tương tự được thực hiện cho các ngôn ngữ lập trình khác. Tôi nghĩ rằng những thay đổi đối với nội bộ của Python sẽ giúp tạo ra kết quả tốt hơn nữa

Sự nhìn nhận

Shannon Jaeger, Jim Uhl và Mike Zastre đã đưa ra nhiều nhận xét hữu ích về bản thảo ban đầu của bài báo này. Các gợi ý của trọng tài ẩn danh cũng đưa ra một số điểm quan trọng mà tôi đã bỏ qua

Cython có nhanh bằng C không?

Cython có cùng tốc độ với chương trình C/C++ được điều chỉnh cẩn thận; . Tôi đã thực hiện nhiều điểm chuẩn của mã số cấp thấp khi triển khai SageMath (sử dụng Cython cho một số dòng mã 100K)

Python có được biên dịch nhanh như C không?

Tuy nhiên, Python có một nhược điểm lớn. Nó chậm hơn nhiều so với các ngôn ngữ được biên dịch như C hoặc C++ .

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

C là ngôn ngữ nhanh hơn so với Python vì nó được biên dịch . Các chương trình Python thường chậm hơn các chương trình C khi chúng được diễn giải. Trong C, loại của các biến khác nhau phải được khai báo khi chúng được tạo và chỉ các giá trị của các loại cụ thể đó phải được gán cho chúng.

Làm cách nào để biên dịch Python thành C?

Biên dịch nhanh Python trong C bằng Cython .
Mang các phần mã của bạn mà bạn muốn chuyển đổi sang c thành một tệp riêng
Cung cấp thông tin về loại và cho Cython biết những gì bạn muốn sử dụng trong Python và những gì bạn không muốn
biên dịch tệp riêng biệt bằng cách sử dụng thiết lập. tập tin py