Pythonのパフォーマンス

実行パフォーマンス #

GraalPyは、GraalVMの最先端のJust-In-Time(JIT)コンパイラを使用します。JITコンパイルされた場合、GraalPyは公式のPythonパフォーマンスベンチマークスイートでCPythonよりも約4倍高速にPythonコードを実行します。

これらのベンチマークは、`pyperformance`パッケージをインストールし、CPythonとGraalPyのそれぞれで`pyperformance run`を呼び出すことで実行できます。Jythonの数値を取得するために、JythonでPython 3のサポートが不足しているため、ハーネスとベンチマークを調整しました。その後、動作するベンチマークのペアワイズの共通部分を取得し、幾何平均を計算することにより、高速化を計算しました。

JITコンパイラがない場合、GraalPyは現在、純粋なPythonコードをCPythonよりも約4倍遅く実行します。これは、非常に短い実行スクリプト、またはOracle JDKまたはOpenJDKでGraalコンパイラなしで実行されるスクリプトは、速度が遅くなることが予想されることを意味します。

機械学習またはデータサイエンスエコシステムからの多くのPythonパッケージには、C拡張コードが含まれています。このコードは、GraalPyのJITコンパイルの恩恵をほとんど受けず、GraalPyでCPython実装の詳細をエミュレートする必要があるという問題があります。多くのC拡張機能が関係する場合、パフォーマンスはネイティブコードとPythonコードの特定の相互作用によって大きく異なります。

コードのロードパフォーマンスとフットプリント #

Pythonコードを解析するには時間がかかるため、GraalPyを使用して別の言語をPythonに埋め込む場合は、コードキャッシングに関連するGraal言語の埋め込みに関する一般的なアドバイスに従ってください。さらに、一部のPythonライブラリでは、作業を行う前に起動時に大量のコードをロードする必要があります。Python言語の設計上、インクリメンタル解析は不可能であり、一部のスクリプトでは、パーサーが実行時間とメモリの znaczny 部分を表す場合があります。これを軽減するために、GraalPyは、適切なファイルシステムアクセスが構成されている場合、解析中に生成されたバイトコードを*.pyc*ファイルにキャッシュできます。

*.pyc*ファイルの作成と管理 #

GraalPyは、対応する*.py*ファイルと一致する無効または存在しない*.pyc*ファイルがある場合、自動的に*.pyc*ファイルを作成します。

GraalPyが実行中にPythonソースファイル(モジュール)を初めてインポートすると、対応する*.pyc*ファイルが自動的に作成されます。 GraalPyが同じモジュールを再びインポートすると、既存の*.pyc*ファイルが使用されます。つまり、まだ実行(インポート)されていないソースファイルの*.pyc*ファイルはありません。 GraalPyはFileSystem APIを介して*.pyc*ファイルを完全に作成するため、Pythonコードが埋め込まれたJavaアプリケーションはファイルシステムアクセスを管理できます。

注:GraalPyは*.pyc*ファイルを削除しません。

GraalPyがその後スクリプトを実行するたびに、既存の*.pyc*ファイルを再利用するか、新しいファイルを作成します。元のソースファイルのタイムスタンプまたはハッシュコードが変更された場合、GraalPyは*.pyc*ファイルを再作成します。 GraalPyは、`source.hashCode()`を呼び出すことによってPythonソースファイルのみに基づいてハッシュコードを生成します。これは、ソースファイルバイトの配列に対するJDKハッシュコードであり、`java.util.Arrays.hashCode(byte [])`で計算されます。

Pythonパーサーのマジックナンバーが変更された場合、GraalPyも*.pyc*ファイルを再作成します。マジックナンバーはPythonのソースにハードコードされており、ユーザーが変更することはできません(もちろん、そのユーザーがPythonのバイトコードにアクセスできる場合を除く)。

GraalPyの開発者は、バイトコード形式が変更されたときにマジックナンバーを変更します。これは実装の詳細であるため、マジックナンバーはGraalPyのバージョン(CPythonのように)に対応する必要はありません。 `pyc`のマジックナンバーは、実行されている実際のPythonランタイムJavaコードの関数です。マジックナンバーの変更はリリースノートに記載されているため、開発者またはシステム管理者はアップグレード時に古い*.pyc*ファイルを削除できます。

*.pyc*ファイルを使用する場合は、少なくともバージョンを切り替えたり、元のソースコードファイルを変更したりするときに、GraalPyへの書き込みアクセスを許可する必要があることに注意してください。そうでない場合、ソースコードファイルの再生成は失敗し、すべてのインポートには、古い*.pyc*ファイルにアクセスし、コードを解析し、シリアル化し、新しい*.pyc*ファイルを書き込もうとして(失敗する)というオーバーヘッドが発生します。ファイル。

GraalPyは、*.pyc*ファイル用に次のディレクトリ構造を作成します

top_directory/
  __pycache__/
    sourceA.graalpy.pyc
    sourceB.graalpy.pyc
  sourceA.py
  sourceB.py
  sub_directory/
    __pycache__/
      sourceX.graalpy.pyc
    sourceX.py

デフォルトでは、GraalPyはソースコードファイルと同じディレクトリレベルに*__ pycache__*ディレクトリを作成し、このディレクトリには同じディレクトリからのすべての*.pyc*ファイルが格納されます。このディレクトリには、異なるバージョンのPython(たとえば、CPythonを含む)で作成された*.pyc*ファイルが格納される場合があるため、ユーザーにはたとえば*.cpython3-6.pyc*で終わるファイルが表示される場合があります。

*.pyc*ファイルは、CPythonと互換性のある方法でGraalPyによって largely 自動的に管理されます。 GraalPyは、CPythonと同様に、t_.pyc_ファイルの場所と、それらがまったく書き込まれるべきかどうかを指定するためのオプションを提供し、これらの両方のオプションはゲストコードによって変更できます。

*.pyc*ファイルの作成は、CPythonと同じ方法で制御できます。

  • GraalPyランチャー(`graalpy`)は、`PYTHONDONTWRITEBYTECODE`環境変数を読み取ります。これが空でない文字列に設定されている場合、Pythonはモジュールをインポートするときに*.pyc*ファイルの作成を試みません。
  • ランチャーのコマンドラインオプション`-B`を指定すると、上記と同じ効果があります。
  • ゲスト言語コードは、実行時に`sys`組み込みモジュールの属性`dont_write_bytecode`を変更して、後続のインポートの動作を変更できます。
  • GraalPyランチャーは、`PYTHONPYCACHEPREFIX`環境変数を読み取ります。設定されている場合、プレフィックスで指定されたパスに*__ pycache__*ディレクトリを作成し、*.pyc*ファイルを格納するためにソースツリーのディレクトリ構造のミラーをオンデマンドで作成します。
  • ゲスト言語コードは、実行時に`sys`モジュールの属性`pycache_prefix`を変更して、後続のインポートの場所を変更できます。

開発者は環境変数またはCPythonオプションを使用してこれらのオプションをGraalPyに伝えることができないため、これらのオプションは言語オプションとして使用できます。

  • `python.DontWriteBytecodeFlag` - `-B`または`PYTHONDONTWRITEBYTECODE`と同等
  • `python.PyCachePrefix` - `PYTHONPYCACHEPREFIX`と同等

Pythonコンテキストは、デフォルトでは*.pyc*ファイルの書き込みを有効にしないことに注意してください。 GraalPyランチャーはデフォルトで有効にしますが、埋め込みユースケースでこれが必要な場合は、*__ pycache__*の場所が適切に管理され、その場所にあるファイルがソースコードファイル(*.py* )と同じ方法で操作から保護されていることを確認するように注意する必要があります。 ) それらが由来する場所。

アプリケーションソースをOracle GraalPyにアップグレードするには、開発者が必要に応じて古い*.pyc*ファイルを削除する必要があることにも注意してください。

セキュリティに関する考慮事項 #

GraalPyは、FileSystem APIを介してすべてのファイル操作(データ、タイムスタンプの取得、および*.pyc*ファイルの書き込み)を実行します。開発者は、カスタム(たとえば、読み取り専用)`FileSystem`実装を使用して、これらのすべての操作を変更できます。開発者は、GraalPyのI / O権限を無効にすることにより、*.pyc*ファイルの作成を事実上無効にすることもできます。

*.pyc*ファイルが読み取り不能な場合、その場所は書き込み可能ではありません。 *.pyc*ファイルのシリアル化データまたはマジックナンバーが何らかの方法で破損している場合、逆シリアル化は失敗し、GraalPyは*.py*ソースコードファイルを再度解析します。これは、モジュールの解析に*のみ*わずかなパフォーマンスの低下を伴いますが、これはほとんどのアプリケーションではそれほど重要ではありません(アプリケーションがPythonコードのロードに加えて実際の作業を実行する場合)。

お問い合わせ