ctypes
ctypesとは
簡単に言うとC言語製の関数を使用するためのライブラリです。
共有ライブラリ(Windowsでは「.dll」、Linuxでは「.so」など)を読み込む形で使用されます。
使用方法
使用したい関数を記述したCコードを用意します。
int fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
そして、共有ライブラリを生成します。gccの場合は
gcc fib.c -shared -o fib.dll
このように「-shared」オプションを付けて生成できます。
あとは「LoadLibrary()」でライブラリを読み込めば使用可能となります。
import ctypes
def c_fib(n):
libc = ctypes.cdll.LoadLibrary("./fib.dll")
return libc.fib(n)
print(c_fib(40))
実行速度
パターン | 実行速度(秒) |
---|---|
Python (3.13.1) のみで計算 | 17.3 |
計算部分は全てctypes | 0.7 |
Nuitka
Nuitkaとは
NuitkaはPythonコードをC言語コードにコンパイルしてくれるコンパイラで、記事執筆現在ではPython2.6~2.7、Python3.4~3.13まで対応しており、サードパーティライブラリ等もわずかに対応してます。
C言語コードにコンパイルするといっても以前紹介したCodonのようにちゃんとコンパイルするわけではなく、高速化はよくて3割程度だと思います。
使用方法
Cコンパイラ
比較的新しめのCコンパイラが必要となります。
MinGW64が使用可能とドキュメントにはありますが、筆者がインストールしたものは使えず、Nuitkaがダウンロードしてそっちを使わされたあげく、セキュリティソフトにウィルス判定されてコンパイルに失敗しました。
特にオプションで指定しなければVisual Studio 2022のコンパイラ(cl.exe)が使用されたのでMinGWでうまくいかないときはVisual Studioをインストールしてみてください。
「nuitka –version」コマンドで使用される環境一覧が取得できます。
ビルドコマンド
以下にビルドコマンド例を示します。
nuitka --standalone --enable-plugin=tk-inter --windows-icon-from-ico="D:\icons\領.ico" --output-filename="amazon" --output-dir="amazon" --windows-console-mode="disable" .\main.py
オプション
主なオプション | 説明 |
---|---|
–standalone | Python環境が整ってなくても動くようにする。配布用にするなら必須。 「XX.dist」フォルダを丸ごと渡せばOK。 |
–onefile | 配布用フォルダごとまるっと一つの実行ファイル(windowsなら.exe)にする。 「–standalone」コマンドも含まれるのでこのオプションを付与した場合は不要。 実行環境を一時ファイルに解凍してから起動するようになるため、若干遅くなる。 |
–enable-plugin | 有効にするプラグインを指定する。 必要なものは指定しないとエラーが出るので、エラーログに従って指定すれば大体うまくいく。 うまくいかないときは使用不可なライブラリ等を使用してるか何かしらのバグ。 |
–windows-icon-from-ico | 実行ファイルのアイコンを指定できる。 OS事に異なる。 これはWindows用。 |
–windows-console-mode | GUIアプリの場合にコンソールが不要なら「disable」を指定する。 これもOS事で異なるオプション。 |
–output-filename | 実行ファイル名を指定できる。 指定しなくても後から名前を変えればいいからどうでもいいオプション。 |
–output-dir | 「XX.build」と「XX.dist」フォルダなどの出力フォルダ名を指定できる。 出力環境をまとめたい几帳面な人用。 |
他にも大事なオプションはあるけどまあどうせアップデートで今後どんどん変更されるだろうからこれくらいで許してください。
実行速度
以下に実行速度の例を挙げておきます。
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
print(fib(40))
言語 | 実行速度(秒) |
---|---|
Python (3.13.1) | 17.3 |
Nuitka (2.5.8) | 12.4 |
C (gcc 14.2.0) | 0.7 |
C (gcc 14.2.0 最適化オプション) | 0.4 |
このように多少は高速化します。
import削減
アプリ開発時によくやるのですが、「test.py」とか「tmp.py」みたいなちょっとしたコードの動作確認用モジュールを作るんですよね。
そこでやりがちなのが「過去使ったライブラリやパッケージのimportをそのままにしておく」ことです。
これが意外と処理時間に関係してきます。
import os
import sys
import datetime
from math import log
import python_bitbankcc
import pandas as pd
import bitbank_ui
from pprint import pprint
import config
import judge_buysell
import trade_log
def main():
print("aaa")
if __name__ == '__main__':
main()
ちょうど個人用アプリで使ってるtest.pyがあるのでそこから引用してみますが、上記のようにやたらめったらimportしたものと、
def main():
print("aaa")
if __name__ == '__main__':
main()
無駄なimportを省いたものとでは以下のように明確に処理時間に差が出ます。
無駄なimport | 処理時間(秒) |
---|---|
あり | 2.1901373 |
なし | 0.0556866 |
積み重なるとかなりの処理時間になるので、できるだけ無駄なものは省きましょう。
まとめ
次はGIL解除版Pythonでも試そうかな?
コメント