差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
programming:python:packages:numba [2020/07/01] – ikatakos | programming:python:packages:numba [2023/10/03] (現在) – ikatakos | ||
---|---|---|---|
行 13: | 行 13: | ||
* PyPy | * PyPy | ||
- | * ほぼ書き換えなしでそれなりに高速化される | + | * 対応している機能が多い |
+ | * 標準ライブラリの処理はほぼ書き換えなしでそれなりに高速化される | ||
+ | * Numpy, Scipyなどの外部ライブラリも、一部はPyPy用が提供されている((要インストール。どこまでちゃんと動くのかは未確認)) | ||
* Pythonとは別の実行環境としてインストールが必要 | * Pythonとは別の実行環境としてインストールが必要 | ||
+ | * 最新のPythonの機能がPyPyに取り込まれるまで、若干のタイムラグはある | ||
* 基本的に実行時コンパイル(JIT) | * 基本的に実行時コンパイル(JIT) | ||
* なので、実行時間に常にコンパイル時間が含まれる | * なので、実行時間に常にコンパイル時間が含まれる | ||
行 27: | 行 30: | ||
* 効果は高い(勿論、書き方や得意分野による) | * 効果は高い(勿論、書き方や得意分野による) | ||
- | 速度比較は、参考文献の1つめが詳しい。 | + | 速度比較は、以下の参考文献のyniji氏の記事が詳しい。 |
PyPyの方が、労力が少なく効果がそこそこでコスパが良い感はある。 | PyPyの方が、労力が少なく効果がそこそこでコスパが良い感はある。 | ||
- | Numbaは、後述のNoPythonモードによって高速化できないコードをエラーにすることが出来るので、着実に高速化させやすい。 | + | Numbaは、後述のNoPythonモードによって高速化できないコードをエラーにできるので、着実に高速化させやすい。 |
- | また、既存コードに未対応の外部モジュールを使っていると、PyPyなら丸ごと実行できなくなる一方 | + | また、未対応の外部モジュールを使っていると、PyPyなら丸ごと実行できなくなる一方、Numbaでは関数を切り分けて、使っていない部分だけコンパイルさせることができる。 |
+ | ((PyPyでも、モジュール不使用の部分だけファイルを切り分けて、本流のPythonからsubprocessで実行するなど可能っちゃ可能)) | ||
===== 参考文献 ===== | ===== 参考文献 ===== | ||
+ | * 公式リファレンス | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
* yniji氏のQiita記事 | * yniji氏のQiita記事 | ||
* [[https:// | * [[https:// | ||
行 54: | 行 62: | ||
高速化する上で重要な概念。 | 高速化する上で重要な概念。 | ||
- | 基本的にNumbaは関数のデコレータに「'' | + | 基本的にNumbaは関数のデコレータに「'' |
未対応の関数やデータ型が含まれる場合、「Objectモード」でコンパイルされる。Objectモードだと、高速化の効果は少ない。 | 未対応の関数やデータ型が含まれる場合、「Objectモード」でコンパイルされる。Objectモードだと、高速化の効果は少ない。 | ||
行 60: | 行 68: | ||
* リファレンス | * リファレンス | ||
- | * [[https:// | + | * [[https:// |
- | そうでなく、全てがNumbaが対応する機能のみで記述されていれば、「NoPythonモード」となり、高速化の効果が大きくなる。 | + | 全てがNumbaが対応する機能のみで記述されていれば、「NoPythonモード」となり、高速化の効果が大きくなる。 |
デコレータとして '' | デコレータとして '' | ||
一方、'' | 一方、'' | ||
- | 既存コードに手を加えたくない場合は '' | + | <sxh python> |
+ | from numba import | ||
- | NoPythonモードで未対応の型(PythonのList)を使用した際の警告例 | + | # Numba非対応の機能 |
- | + | from collections import defaultdict | |
- | | + | |
- | | + | @jit |
+ | def func1(): | ||
+ | d = defaultdict(int) | ||
+ | return d | ||
+ | |||
+ | print(func1()) | ||
+ | |||
+ | # => | ||
+ | # NumbaWarning: | ||
+ | # Compilation | ||
+ | # because Function " | ||
+ | # Untyped global name ' | ||
+ | # ... | ||
+ | # NumbaWarning: | ||
+ | # | ||
+ | # defaultdict(< | ||
+ | # | ||
+ | # 警告は出るが実行はされる | ||
+ | |||
+ | |||
+ | @njit | ||
+ | def func2(): | ||
+ | d = defaultdict(int) | ||
+ | return d | ||
+ | |||
+ | print(func2()) | ||
+ | |||
+ | # => | ||
+ | # numba.core.errors.TypingError: | ||
+ | # Untyped global name ' | ||
+ | # | ||
+ | # エラー終了 | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | 既存コードに手を加えたくない場合は '' | ||
+ | |||
+ | ただ、'' | ||
+ | |||
+ | * [[https:// | ||
以下、基本的にNoPythonモードを満たすように記述することを目標とする。 | 以下、基本的にNoPythonモードを満たすように記述することを目標とする。 | ||
行 81: | 行 130: | ||
数値型とnumpy.ndarrayしか使えないくらいに思っておいてよい。 | 数値型とnumpy.ndarrayしか使えないくらいに思っておいてよい。 | ||
- | 一応SetやDictも使える。(ただしnumpy.ndarray等と比較して動作は速くない) | + | 一応SetやDictも使える。(ただし高速化の恩恵は若干少なくなる) |
引数や戻り値のような、Numba関数の中と外の橋渡し的な役割をする変数は、特に留意が必要となる。 | 引数や戻り値のような、Numba関数の中と外の橋渡し的な役割をする変数は、特に留意が必要となる。 | ||
行 88: | 行 137: | ||
==== 引数・戻り値に使える主な型 ==== | ==== 引数・戻り値に使える主な型 ==== | ||
- | * 数値(byte, | + | * ★数値(byte, |
- | * numpy.ndarray | + | * ★numpy.ndarray |
- | * UniTuple, Tuple | + | * ★UniTuple, Tuple(※) |
- | * (*1) list, set(reflected list, reflected set) | + | * (*1) 通常のlist, set(reflected list, reflected set)(※) |
+ | * (*2) Numba独自のList, | ||
* (*2) Unicode文字列(Python3における通常の文字列) | * (*2) Unicode文字列(Python3における通常の文字列) | ||
- | | + | * コンパイル済み関数(※) |
- | | + | |
- | * 引数としてのみ使用可 | + | |
- | その他もあるかも知れないけど、どこ見れば書いてあるのかよくわかってない。 | + | その他もあるかも知れない。 |
- | なるべく上の3つのみを使うようにした方がよさそう。(個々の問題点は後述) | + | |
- | (*1)はdeprecatedで今後使えなくなる可能性が高い。 | + | なるべく★を付けた3つのみを使うようにした方がよさそう。 |
+ | (*1)はdeprecatedで今後使えなくなる可能性が高い。\\ | ||
(*2)は、対応はしているが、まだ十分高速に動くようコンパイル出来ない場合があるとリファレンスに書かれている。 | (*2)は、対応はしているが、まだ十分高速に動くようコンパイル出来ない場合があるとリファレンスに書かれている。 | ||
+ | |||
+ | (※)を付けたものは、下記でもう少し詳しく記述している。 | ||
== UniTuple, Tuple == | == UniTuple, Tuple == | ||
- | タプルは、複数の要素をまとめることが出来る。要素の型が全て統一されているかどうかで区別される。 | + | タプルは、複数の要素をまとめることが出来る。戻り値として複数の値を返す場合に重宝する。 |
+ | |||
+ | 要素の型が全て統一されているかどうかで大きく以下の2つに区別される。 | ||
- | * UniTuple: | + | * UniTuple: 統一されている(homogeneous) |
- | * Tuple: | + | * Tuple: 複数の型が混在している(heterogeneous) |
- | heterogeneousなTupleは、変数によるindexアクセスなどいくつかの機能が使えない(型を特定できないのでそりゃそう)。 | + | 混在しているTupleは、変数によるindexアクセスなどいくつかの機能が使えない(型を特定できないのでそりゃそう)。 |
また、イテレートするときに特殊な書き方が必要となる。 | また、イテレートするときに特殊な書き方が必要となる。 | ||
- | * [[https:// | + | * [[https:// |
- | 引数や戻り値のために一瞬使うだけなら大した影響はないだろうが、内部でガッツリ使う場合はなるべくUniTupleな構造にした方がよい。 | + | 引数や戻り値のために一瞬使うだけなら大した影響はないだろうが、内部で使う場合はなるべくUniTupleな構造にした方がよい。 |
型指定の書き方は、以下のようにする。 | 型指定の書き方は、以下のようにする。 | ||
行 127: | 行 179: | ||
== reflected list と numba.typed.List == | == reflected list と numba.typed.List == | ||
- | * [[https:// | + | * [[https:// |
- | どちらも、Pythonのlist機能をNumbaで出来る範囲で表現することを目的としたデータ構造。 | + | どちらも、Pythonのlist機能に似せたようなデータ構造。一応、以下の違いがある。 |
- | * reflected list: Pythonのlistをそのまま受け取ってNumba内で解釈できるようにしたもの | + | * reflected list: 見た目上の扱いはPythonのlistのまま、制約を加えてNumbaで解釈できるようにしたもの |
* typed list: Numba独自のリスト構造クラス | * typed list: Numba独自のリスト構造クラス | ||
- | reflected list は deprecated。下記を読むと、ネスト等で複雑になると限界があるので typed listに置きかえていく方針らしい。 | + | reflected listは deprecated。ネスト等で複雑になると限界があるのでtyped listに置きかえていく方針らしい。\\ |
+ | そのため、(今のところ問題なく使えるものの)ver.0.45以降ではその旨の警告が出る。 | ||
* [[http:// | * [[http:// | ||
- | |||
- | そのため、reflected list は(問題なく使えるものの)ver.0.45以降では警告が出る。 | ||
また、typed listの方は「実験的機能」とされていて、バグがあったり、高速化の恩恵が少なくなる可能性が言及されている。 | また、typed listの方は「実験的機能」とされていて、バグがあったり、高速化の恩恵が少なくなる可能性が言及されている。 | ||
行 149: | 行 200: | ||
* reflected list | * reflected list | ||
- | * 外部から与える際は、ネストは不可。要素の型は統一されている必要がある | + | * 外部から与える際はネスト不可、Numba関数内部で生成する場合はネスト可 |
- | * Numba関数内部では、ネスト可能 | + | * Numba関数内部で「'' |
- | * Numba関数内部で「'' | + | |
* typed.List | * typed.List | ||
* ネスト可 | * ネスト可 | ||
- | * '' | + | * 一度に生成することはできなくて、'' |
また、Pythonのデータ構造にはListの他にSet, | また、Pythonのデータ構造にはListの他にSet, | ||
行 198: | 行 248: | ||
== コンパイル済み関数 == | == コンパイル済み関数 == | ||
- | * [[https:// | + | * [[https:// |
- | 引数としてのみ使え、戻り値には出来ない。 | + | ほとんどの処理が同じで一部だけ異なる場合、関数を外部注入したいことはある。 |
- | また、関数を引数とする関数を事前コンパイルする方法がわからない。感触的には無理っぽい。 | + | Numbaでは、関数オブジェクトは引数としてのみ使え、戻り値には出来ない。また、(おそらく)関数を引数とした関数はキャッシュや事前コンパイルは出来ない。 |
- | まず、型指定の記述方法が不明。型指定しないと事前コンパイルは出来ない。 | + | まず、事前コンパイルには型指定が必須だが、その記述方法が不明。 |
- | + | 一応、後述の「[[# | |
- | 一応、型指定しない '' | + | |
- | これを他の関数の型指定に用いることが出来る。 | + | |
<sxh python> | <sxh python> | ||
@njit(' | @njit(' | ||
- | def double(a): | + | def double(a): |
return 2 * a | return 2 * a | ||
@njit | @njit | ||
- | def fumidai(func, | + | def fumidai(func, |
return func(a) | return func(a) | ||
- | fumidai(double, | + | fumidai(double, |
@njit(fumidai.nopython_signatures[0]) | @njit(fumidai.nopython_signatures[0]) | ||
- | def hontai(func, | + | def hontai(func, |
- | return func(a) | + | return func(a) |
- | hontai(double, | + | hontai(double, |
</ | </ | ||
しかし、 | しかし、 | ||
- | * '' | + | |
- | * double以外の関数を定義して渡すと「'' | + | |
+ | * < | ||
+ | * 異なる関数を与えることはできない | ||
+ | * '' | ||
+ | * < | ||
+ | * 結局決まった関数しか渡せないなら、引数にしなくてもグローバルで定義して呼び出すのと変わんない | ||
- | 実体のあるオブジェクトでなく参照として渡しているので、関数を置きかえたり、ファイルとして残すことはできないらしい。 | + | 実体のあるオブジェクトでなく参照として渡されるので、関数を置きかえたり、ファイルとして残すことはできないらしい。 |
- | 有効に使える場面は限られるか。 | + | '' |
+ | せいぜい、異なる関数を引数とするたびに別々の関数としてコンパイルされるので、与える関数の種類は少ないに越したことはない、というくらい。 | ||
+ | キャッシュしたい場合は、関数は引数としても使えないと考えておいた方がよいだろう。 | ||
行 248: | 行 303: | ||
特にdictは、イテレータのように渡されるのか、最初のkey-valueの組合せで型が確定する。例えば、int→floatはキャストできるが、float→intはできないため、以下のようになる。 | 特にdictは、イテレータのように渡されるのか、最初のkey-valueの組合せで型が確定する。例えば、int→floatはキャストできるが、float→intはできないため、以下のようになる。 | ||
- | d = {2: 2.0, 3: 3} はOK (key, value) = (int64, float64) | + | d = {2: 2.0, |
| | ||
- | d = {2: 2, 3: 3.0} はエラー | + | d = {2: 2, |
- | ただ、使ってみた感触としてはこれらのパフォーマンスはあまり優れているとは言えない。実行時間が数倍遅くなることもある。なるべくならNumpy配列を使った方がよい。 | + | ただ、使ってみた感触としてはこれらのパフォーマンスはあまり優れているとは言えない。 |
+ | 実行時間が数倍遅くなることもある(それでもNumbaを使わないよりは十分速いが)。なるべくならNumpy配列を使った方がよい。 | ||
また、Set, | また、Set, | ||
行 297: | 行 353: | ||
* [[https:// | * [[https:// | ||
* 未実装 | * 未実装 | ||
+ | * [[https:// | ||
* [[https:// | * [[https:// | ||
* 未実装 | * 未実装 | ||
* accumulate, combinations 等は使えない | * accumulate, combinations 等は使えない | ||
+ | * accumulateに関しては、[[https:// | ||
* [[https:// | * [[https:// | ||
* 意外と(? | * 意外と(? | ||
+ | ==== Numpy関数 ==== | ||
+ | 公式にまとまってる。 | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | それなりに対応しているが、関数自体は存在してもオプション引数は未対応のものも多い。 | ||
+ | |||
+ | 個人的に axis オプションはよく使うが、未対応なのはもどかしい。 | ||
+ | |||
+ | === 速度 === | ||
+ | |||
+ | 無理にNumpy関数を使わずとも、単純なforループで代替可能な処理はforループで書いた方が速いこともある。 | ||
+ | |||
+ | NumPy関数の多くは非破壊的に、結果は新しい配列を生成して返すため、生成コストが発生する。 \\ | ||
+ | 引数 '' | ||
+ | |||
+ | 破壊的な処理で問題ない場合は特に、forループで更新していく方が速い。 | ||
+ | |||
+ | たとえば、2つの配列で同じindex同士の最大値を求める場合、'' | ||
+ | |||
+ | ++++ テスト例 | | ||
+ | |||
+ | <sxh python> | ||
+ | import sys | ||
+ | from timeit import timeit | ||
+ | |||
+ | import numpy as np | ||
+ | |||
+ | |||
+ | def solve1(n, aaa, bbb): | ||
+ | return np.maximum(aaa, | ||
+ | |||
+ | |||
+ | def solve2(n, aaa, bbb): | ||
+ | for i in range(n): | ||
+ | aaa[i] = max(aaa[i], bbb[i]) | ||
+ | return aaa | ||
+ | |||
+ | |||
+ | from numba import njit | ||
+ | |||
+ | solve1 = njit(' | ||
+ | solve2 = njit(' | ||
+ | print(' | ||
+ | |||
+ | n = 10 ** 7 | ||
+ | aaa = np.random.randint(0, | ||
+ | bbb = np.random.randint(0, | ||
+ | |||
+ | print(timeit(' | ||
+ | print(timeit(' | ||
+ | |||
+ | # => | ||
+ | # 4.919 | ||
+ | # 1.482 | ||
+ | </ | ||
+ | |||
+ | ++++ | ||
===== グローバル変数 ===== | ===== グローバル変数 ===== | ||
行 327: | 行 443: | ||
</ | </ | ||
+ | グローバル変数がリストなどのオブジェクトの場合、エラーとなる(この辺の詳細な条件は要確認)。 | ||
+ | |||
+ | <sxh python> | ||
+ | from numba import njit | ||
+ | |||
+ | glb = [1, 2, 3] | ||
+ | |||
+ | @njit(' | ||
+ | def global_test(): | ||
+ | return glb[-1] | ||
+ | |||
+ | </ | ||
+ | |||
+ | 一方で、「大枠のNumba関数内で、リストもクロージャー関数も定義し、クロージャー関数からリストにアクセス」する場合はOK。コンパイル後の変更もちゃんと反映される。 | ||
+ | |||
+ | <sxh python> | ||
+ | from numba import njit | ||
+ | |||
+ | @njit(' | ||
+ | def solve(): | ||
+ | glb = [[1, 2, 3]] # 変数定義自体は関数より前が必須 | ||
+ | |||
+ | def global_test(): | ||
+ | return glb[-1] | ||
+ | |||
+ | print(global_test()) | ||
+ | |||
+ | glb.append([4, | ||
+ | print(global_test()) | ||
+ | |||
+ | glb = [[7, 8, 9]] | ||
+ | print(global_test()) | ||
+ | |||
+ | solve() | ||
+ | </ | ||
===== 型指定 ===== | ===== 型指定 ===== | ||
- | '' | + | '' |
+ | |||
+ | 事前コンパイルには必須となる。 | ||
+ | |||
+ | 型指定が無いと、必然的に実行時コンパイルとなり、実際に呼び出されたときの引数に応じて型推論してからコンパイルされる。 | ||
+ | |||
+ | 型を指定すると事前コンパイルが可能になるほか、以下の恩恵を期待できる。 | ||
+ | |||
+ | * 予期せぬ重複コンパイルを防止できる | ||
+ | * JITは、引数の型が異なる呼び出しのたびに、別々の関数としてコンパイルされる | ||
+ | * float型でコンパイル済みのJIT関数に、うっかりint型を与えると、必要ないのに新規コンパイルが走ってしまう | ||
+ | * 読んだだけで挙動を想定しやすいコードになる | ||
+ | * よりメモリ効率を改善できる | ||
+ | * intやfloatは、(実行環境によるが、通常)64bit型としてコンパイルされる | ||
+ | * 8bitで済むような変数はそう明記することで、メモリ効率を改善でき、若干の高速化にも繋がる | ||
+ | |||
+ | |||
+ | ==== 記述方法 ==== | ||
- | 指定が無いと、関数が呼ばれたときの引数に応じて型推論してからコンパイルされるのに対し、 | + | 「戻り値の型(引数1の型, 引数2の型, ...)」のように記述する。戻り値の型を省略した場合は推論される。 |
- | 型を指定すると指定した型に向けたコンパイルしか行われないので、 | + | |
- | 「より頑健なコードになる」「8bitで済むような変数に64bit割り当てられるなどが無くなり、より高速化できる」などの恩恵が期待できる。 | + | |
- | 「戻り値の型(引数1の型, | ||
numbaで定義された型指定用クラスを使う方法と、文字列を使う方法があるが、文字列を使った方がimportなどの手間が省ける。 | numbaで定義された型指定用クラスを使う方法と、文字列を使う方法があるが、文字列を使った方がimportなどの手間が省ける。 | ||
- | 戻り値の型を省略した場合は推論される。 | ||
文字列とデータ型の対応は以下の通り。 | 文字列とデータ型の対応は以下の通り。 | ||
- | * [[https:// | + | * [[https:// |
- | 型指定用のクラスは '' | + | 型指定用のクラスは '' |
- | また、配列は '' | + | また、'' |
<sxh python> | <sxh python> | ||
行 374: | 行 538: | ||
</ | </ | ||
+ | |||
+ | ==== 推論させた型指定 ==== | ||
+ | |||
+ | 型をどう記述すればいいかわかんない、という場合、一旦JITを走らせて推論させた型でもって、AOT用の型指定とさせることも(一応)できる。 | ||
+ | |||
+ | 以下のコード、'' | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | 毎回、型推論のためにダミー実行させるのも無駄なので、以下の例ではコンパイルさせたい場合に限り実行時オプションに compile を付けることで区別している。 | ||
+ | |||
+ | |||
+ | <sxh python> | ||
+ | |||
+ | if sys.argv[1] == ' | ||
+ | from numba import njit | ||
+ | from numba.pycc import CC | ||
+ | |||
+ | def func(a, b): # コンパイルしたい関数 | ||
+ | return a + b | ||
+ | | ||
+ | fumidai = njit(func) | ||
+ | |||
+ | fumidai(1.5, | ||
+ | # この時点でこの引数型に対するJITが走る | ||
+ | # float64(float64, | ||
+ | |||
+ | # 同じ関数を、fumidaiで推論された型でもって型指定、事前コンパイル | ||
+ | cc = CC(' | ||
+ | cc.export(' | ||
+ | cc.compile() | ||
+ | |||
+ | from my_module import hontai | ||
+ | |||
+ | print(hontai(3.5, | ||
+ | print(hontai(5, | ||
+ | |||
+ | </ | ||
+ | |||
+ | また、ここまで自動化しなくても、一度ダミー実行させた関数の '' | ||
+ | ただし、'' | ||
+ | |||
+ | ===== クラス ===== | ||
+ | |||
+ | '' | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | * 事前コンパイル(AOT)はできず、実行時コンパイル(JIT)のみ | ||
+ | * [[https:// | ||
+ | * '' | ||
+ | * [[https:// | ||
+ | * 事前にクラス変数の型を、'' | ||
+ | * [[https:// | ||
+ | * そのため、関数や他のクラスなど、型指定できない(難しい)型はクラス変数に持ちにくい | ||
+ | * どのように指定するかは上記ドキュメント参照 | ||
+ | * nopythonモードでコンパイルを試みられる | ||
+ | * うっかりobjectモードになってて高速化の恩恵が少なかった、などの心配は無い | ||
+ | |||
+ | 複雑なクラスになるとコンパイルに何十秒とかかってしまう。\\ | ||
+ | もちろん何回も使うのであれば十分にお釣りが来るが、(今のところ)AOTやキャッシュが出来ない以上、使いどころは選ぶ必要がある。 | ||
+ | |||
+ | ==== 型指定の例 ==== | ||
+ | |||
+ | |'' | ||
+ | |'' | ||
+ | |'' | ||
+ | |'' | ||
+ | |'' | ||
+ | |||
+ | '' | ||
+ | |||
+ | typeofを使えば一応は関数や独自クラスの型もわかるが、'' | ||
+ | 結局、型と言うよりは「メモリのどこどこに記録されたオブジェクト」という感じで、 | ||
+ | '' | ||
+ | 同質の他のオブジェクトを渡すとエラーになる。 | ||
+ | |||
+ | <sxh python> | ||
+ | |||
+ | function_for_type_check = numba.njit()(lambda: | ||
+ | function_truly_want_to_use = numba.njit()(lambda: | ||
+ | |||
+ | spec = [ | ||
+ | (' | ||
+ | ] | ||
+ | |||
+ | @numba.experimental.jitclass(spec) | ||
+ | class A: | ||
+ | def __init__(self): | ||
+ | self.func = function_truly_want_to_use | ||
+ | </ | ||
===== 事前コンパイル(AOT) ===== | ===== 事前コンパイル(AOT) ===== | ||
行 379: | 行 634: | ||
'' | '' | ||
- | * [[https:// | + | * [[https:// |
PCにCコンパイラがインストールされている必要がある。 | PCにCコンパイラがインストールされている必要がある。 | ||
行 386: | 行 641: | ||
* [[https:// | * [[https:// | ||
- | コンパイル時点で引数・返値の型がわかっている必要がある。 | + | 型指定が必須となる。 |
- | 明示的に型を与える場合はよいが、'' | + | |
- | + | ||
- | * [[https:// | + | |
使う際は、通常のモジュールと同様 '' | 使う際は、通常のモジュールと同様 '' | ||
コンパイル後に出来るファイルは '' | コンパイル後に出来るファイルは '' | ||
- | IDEでは、「そんなモジュール無いで」という構文エラーが出たり、引数の型補間が行われない可能性はある。 | ||
+ | < | ||
+ | 2023/10 | ||
+ | |||
+ | pycc モジュールは、近く非推奨になるらしい。 | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | ざっと見たところでは、distutils モジュールが Python 3.12 で削除される予定であるが、pyccはそれに依存しているとのこと。 | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | で、pyccで生成されるコードはjitでコンパイルされるコードと非互換だし制限が多いしで、これを機に他の方法を作った方がよいと判断されたらしい。 | ||
+ | |||
+ | 代替手段が用意されるまではpyccは維持される、と書いてはいる(本当に信じていいかはわかんない。Python3.12 がメジャーになるまでのタイムリミットもあるし)ので、しばらくはAOTが必要なら使い続けてよいだろうが、Python本体の3.12へのアップデートは少し調べてからの方がいいし、どうしてもというわけでなければJITへの切り替えも考えた方がよいかも。 | ||
+ | </ | ||