pycom - C++ を使用したネイティブ コードに至るまでの Python コンパイラ

(A Python compiler, down to native code, using C++)

Created at: 2022-07-16 17:26:42
Language: C++
License: MIT

Pycom: Python コンパイラ

README.md という名前になっているのには理由があります。新しい問題を作成する前に、よくお読みください。

対応プラットフォーム: Windows、Linux

目次

インストール

単に:

git clone https://github.com/Omyyyy/pycom.git
cd pycom
pip install -e .

pycom.py.egg-info
注:最後のコマンドが作成するフォルダーには触れないでください。それ以外の場合は機能しません。

使用法

インストール手順に正しく従った場合、これはすべてのディレクトリで機能します。

pycom (フラグ) [ソースファイル]

フラグ

  • -i
    | |
    --info
    (ブール値):
    コンパイルに関する追加情報 (かかった時間など) を出力します。デフォルトはオフです。

  • -r
    | |
    --run
    (bool):
    生成された実行可能ファイルをコンパイル後に自動的に実行します。デフォルトはオフです。

  • -rd
    | |
    --runandelete
    (bool):
    コンパイル後に生成された実行可能ファイルを自動的に実行し、その後削除します。デフォルトはオフです。

  • -o
    | |
    --output
    [出力] (文字列):
    フラグの後に指定された文字列は、生成された実行可能ファイルの名前になります。デフォルトは、渡された Python ファイルの名前です。

  • -fm
    | |
    --fastmath
    (bool):
    いくらかの精度を犠牲にして、積極的な最適化を計算速度で実行します。デフォルトはオフです。

  • -c
    | |
    --check
    (bool):
    実際にコンパイルせずにプログラムがコンパイルされるかどうかを確認します。デフォルトはオフです。

Python の依存関係:

Python バージョン 3.10 以降

C++ の依存関係:

g++ コンパイラの最新バージョン
Boost C++ ライブラリ。ここからダウンロード: https://www.boost.org/users/history/version_1_79_0.html (フォルダーを usr/gcc/include/ に配置)

テストを実行する

まず、テスト用の依存関係をインストールします

pip install -r test-requirements.txt

次に、でテストを実行できます

# Unit tests
pytest tests
# Integration tests
pytest integration

パイコムとは?

Pycom は実質的に Python コードのコンパイラであり、「中間表現」として C++ を使用してネイティブ実行可能ファイル (Python 解釈の 20 ~ 30 倍の速度) に変換します。多くの標準ライブラリと組み込み関数とともに、ほとんどすべての Pythonic 構文をサポートしています。現在サポートされているものとサポートされていないものを確認するには、以下の のセクションを確認してください。

なぜ、いつ Pycom を使用するのですか?

Python は遅いです。多くの最適化と新しい実装により速度が大幅に改善されましたが、Python コードからスタンドアロンの実行可能ファイルとして実行できるネイティブ コードを生成することは、実際には行われていません。その結果、Python コードは C/C++ のレベルの速度と移植性に達したことはありません。Pycom はこれに取り組むことを目指しています。

Pycom (現在) はすべてのバージョンのすべての Python 機能をサポートしていないため、単純なアプリケーションを実行したい場合にのみ使用してください (繰り返しますが、を確認してください) 。

Pycom がサポートし、得意とすること:

反復回数の多いループ:

for i in range(1, 1000001):
    if i % 3 == 0:
        print(i)
def is_prime(n):
    if n == 1:
        return 0
    for i in range(2, n):
        if n%i == 0:
            return 0

    return 1

def main():
    total = 0
    for i in range(1, 101):
        total += is_prime(i)

    print(total)

速度のベンチマークと比較

基準 CPython パイコム --fastmath を使用した Pycom ピーピー
3 と 5 の倍数 9.383秒 0.133秒 0.106秒 0.495秒
素数 17.127秒 4.441秒 3.994秒 4.577秒
スタック操作 8.857秒 2.132秒 1.992秒 3.113秒

(これらはすべて の下にあります

./benchmarks
)

サポートされる機能

  • Python のすべての 'turing complete' 機能:
    if
    else
    for
    while
    など。
  • f''
    文字列
  • 組み込み関数の一部
  • 一部の数学ライブラリ関数
  • リスト内包表記
  • Python スタイルの任意の大きな整数

まだサポートされていません

  • 特定のブロックを Python で書く方法 (1 行
    if
    ...
    else
    など)
  • 複数行の文字列リテラル
  • stdlib に含まれる多くのライブラリ
  • クラス
  • throw
    and
    finally
    キーワード_
  • 異種リスト。複数のデータ型を含むリスト

CPython との小さな癖と違い:

  • のような整数変数を宣言すると
    n = 3
    、これは Python の任意のサイズの整数ではなく、C++ 64 ビット整数として解釈されます。無限サイズの整数を宣言するには、次を使用します
    n: int = 3
  • Python ソースではセミコロンを使用しないでください。Pycom はエラーをスローします。
  • if __name__ == "__main__": 
    タイプのものをサポートできません。
    main()
    関数はすでにエントリポイントです
  • コードに関数がない場合は、通常どおりにすべてを実行できます。
print("Hello, World") # This will compile
  • ただし、少なくとも 1 つのユーザー定義関数がある場合、開始点は main() 関数ブロック内にある必要があります。
def printhello():
    print("Hello!")

def main():
    printhello() 

# Will compile 
def printhello():
    print("Hello!")

printhello() 

# Will not compile

不便ですし、後者もいつかサポートされるかもしれませんが、今のところはこんな感じです。また、

main()
関数がある場合、エントリ ポイントとして値を返すことはできません。コンパイラはエラーをスローします。

私はこれらの例外と癖を取り除き、Pycom と CPython を完全に同一にするように努めますが、現時点では非常に実験的であり、改善の余地がかなりあります。