Nuitka デコンパイラの評価

Nuitka でコンパイルしたプログラムから、元の Python ソースコードをどこまで復元できるかを毎日 1 回評価しています。

Nuitka
Python を C に変換し、C コンパイラ(GCC)でバイナリにするコンパイラです。
本ツール(図の our decompiler)
デコンパイラ angr を拡張し、Nuitka でコンパイルされたバイナリから Python のソースコードを復元します。

復元したソースコードが元のテストに通るか、元と比べて長さや認知的複雑度がどれだけ違うかを測ります。あわせて、本ツールと angr 単体の擬似 C の出力を比べます。

正しさの評価

元のプログラムの関数を、復元した関数に差し替え、データセットのテスト入力に対して元と同じ結果を返すかを確かめます。テストの実行時間の上限は関数ごとに 30 秒です。データセットの名前のリンクからは、そのデータセットの関数の一覧に飛べます。

dev / holdout
評価する関数を 2 つの区分に分けたものです。dev を見ながら本ツールを開発し、holdout は開発中に見ないでおくことで、開発で見ていないソースコードでの性能を確かめます。
合格
テストに通ったことを指します。
不合格
テストに通らなかった、テストが時間切れになった、または出力にその関数がなかったことを指します。
エラー
本ツールが異常終了した、時間切れになった、または Python を出力しなかったことを指します。
データセット合格不合格エラー合計
dev/cruxeval725063788
dev/humaneval_plus15808166
dev/thealgorithms169703982095
dev 合計258004693049
holdout/mbpp_plus166037203
holdout 合計166037203
合格不合格エラー

読みやすさの評価

行数と認知的複雑度は、値が小さいほどソースコードが読みやすいことを意味します。平均は関数 1 つあたり、合計はデータセット全体の値です。認知的複雑度は、分岐やループを入れ子の深さで重み付けして数えた指標です。

Python

元のソースコードと復元したソースコードを比較します。対象は合格した関数だけです。

データセット合格行数の平均 (original → ours)認知的複雑度の平均 (original → ours)
dev/cruxeval7255.3 -> 6.21.8 -> 1.9
dev/humaneval_plus15817.1 -> 18.93.1 -> 3.9
dev/thealgorithms169720.1 -> 21.93.3 -> 4.4
dev 合計258015.8 -> 17.32.9 -> 3.7
holdout/mbpp_plus1663.5 -> 4.91.3 -> 1.5
holdout 合計1663.5 -> 4.91.3 -> 1.5

擬似 C

本ツールが内部で使用する中間表現から擬似 C のソースコードを作成し、angr の出力と比較します。対象は両方がそろう関数すべてで、合格したかどうかは問いません。angr は Nuitka 向けの処理を持たないので、本ツールの追加した処理で定型処理をどれだけ取り除けたのか、また Python の演算にどれだけ戻せたのかを計算できます。

定型処理
Python のソースコードには現れない CPython の管理処理(参照カウント、フレーム、エラーの伝播)の呼び出しと、メモリへの書き込みです。
Python 演算
Python の演算(加算やフィールドの参照など)のうち、C の関数呼び出しのまま残っているものです。
angr の定型処理の割合
angr の擬似 C における定型処理 ÷(定型処理 + Python 演算)です。
データセット関数の数angr の定型処理の割合定型処理の合計 (angr → ours)Python 演算の合計 (angr → ours)行数の平均 (angr → ours)認知的複雑度の平均 (angr → ours)
dev/cruxeval78785.4%45705 -> 2367843 -> 63269.4 -> 28.2179.6 -> 3.8
dev/humaneval_plus16683.4%10802 -> 52157 -> 11305.3 -> 32.4232.9 -> 5.3
dev/thealgorithms208580.4%168099 -> 139540856 -> 625421.4 -> 44.7446.6 -> 8.4
dev 合計303881.5%224606 -> 163650856 -> 699375.7 -> 39.7365.8 -> 7.0
holdout/mbpp_plus20386.2%9289 -> 21484 -> 32202.2 -> 22.0145.0 -> 2.3
holdout 合計20386.2%9289 -> 21484 -> 32202.2 -> 22.0145.0 -> 2.3

元のソースコードと復元したソースコードの比較

各点は合格した 1 つの関数を表しています。横軸は元の関数の値、縦軸は復元した関数の値です。目盛りは等間隔ではなく、平方根スケールで小さい値の変化が見やすくなるよう調整されています。例えば、「same」の線上の点は復元値が元と同じであること、「2x」の線上の点は 2 倍になったことを示します。点をクリックすると関数の詳細を表示できます。

行数

dev元の関数と復元した関数の行数の比較中央値 11 → 13
holdout元の関数と復元した関数の行数の比較中央値 2 → 3

認知的複雑度

dev元の関数と復元した関数の認知的複雑度の比較中央値 2 → 2
holdout元の関数と復元した関数の認知的複雑度の比較中央値 0 → 0

限界

データセット

元の Python ソースコードの著作権は各データセットの作者にあり、ソースコードはそれぞれのデータセットのライセンスに従います。

データセット出典ライセンス
cruxevalhttps://github.com/facebookresearch/cruxeval/tree/10d71b4ca99f2b6624bef9533ade5a0594ab7716MIT
humaneval_plushttps://github.com/evalplus/humanevalplus_release/tree/68cd26d53a0dec69f85eafe1f82a2a74155a2bd6Apache-2.0, MIT
mbpp_plushttps://github.com/evalplus/mbppplus_release/tree/64fc4195b858a17cdfdb3324f0baf37939144e14Apache-2.0, CC-BY-4.0
thealgorithmshttps://github.com/TheAlgorithms/Python/tree/f8084d92b2df4faecad57e0cd8c5ab2adbbf8b19MIT

環境

dev

holdout