Nクイーン問題(66) Python-codonで高速化

ソースコード

今回の連載 python/pypy/codonのソースコードディレクトリはこちら
https://github.com/suzukiiichiro/N-Queens/tree/master/10Bit_Python

Nクイーン問題 過去記事アーカイブ

【過去記事アーカイブ】Nクイーン問題 過去記事一覧
https://suzukiiichiro.github.io/search/?keyword=Nクイーン問題
【Github】エイト・クイーンのソース置き場 BashもJavaもPythonも!
https://github.com/suzukiiichiro/N-Queens

python/pypy/codon について

Pythonはとにかく遅いです。
でもコーディングをしていて楽しいし、きれいなソースを書かないと動かないので、誰が書いたpythonコードであっても読みやすいです。さらに広範なバリエーションのモジュールをインストールすればほとんど苦労せずにあらゆるアルゴリズムを使うことができます。ただ遅いんです。

そこで、python高速化を追求した人がいました。

Pythonの実行を高速化する方法を一覧でまとめてみた
https://qiita.com/yuki_2020/items/36da0281c8af5c2c745f

どうやらcodonなるものを使うと驚きの速さでpythonが実行できるようです。ではまずはPythonのインストールを済ませ、プログラミング協議会定番のpypyの構築、そして最終段階でcodonのインストールを説明していきます。

次回からはこれまでのN-QueeensのPyhonコードをcodon化していきます。
なぜpypyを飛ばすのか。。。それは、pypyはpythonのコードに全く手を入れることなく高速化できるから、特別奥義は必要ないのです。

# 通常のpythonコードの実行
$ python <filename.py>

# pypyのpythonコードの実行
$ pypy <filename.py>

pypyは10倍程度の高速化が見込めます。
再帰に限定されますが、ソースの冒頭に以下の追記するとpypyコードはさらに高速化されます

# pypyで再帰が高速化できる
import pypyjit
pypyjit.set_param('max_unroll_recursion=-1')

codonに関しては以下のリンクが参考になります。

あなたのPythonを100倍高速にする技術 / Codon入門
https://zenn.dev/turing_motors/articles/e23973714c3ecf

pythonのインストール

以下のwhichコマンドでpythonがインストールされていないようであれば、

$ which python

以下を参考にpythonをインストールします
pyenvでのインストールが慣例のようです。

git clone git://github.com/yyuu/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc

Python環境のインストール. 共有ライブラリもインストールします

$ CONFIGURE_OPTS=--enable-shared pyenv install 3.10.10

pythonのversionsの確認

$ pyenv versions

* system (set by /home/suzuki/.pyenv/version)
  3.10.0

pyenvでは全ての環境(global)とローカル環境(local)それぞれにpythonのバージョンを指定してインストールすることができます。

3.10.0 をglobalのデフォルトにして確認

$ pyenv global 3.10.0
$ pyenv versions
  system
* 3.10.0 (set by /home/suzuki/Github/.python-version)

必要なモジュールはpipコマンドで追加インストールします

$ sudo python3 -m ensurepip
$ sudo python3 -m pip install psutil

pypy のインストール

PyPy(パイパイ)は、プログラミング言語Pythonの実装の1つで、CPython(通常のPython)よりも高速に動作する処理系です。

【特徴】
Pythonで記述されたPythonの処理系(セルフホスティング)
CPythonとの互換性に重点を置いている
Just-in-Time(JIT)コンパイルというシステムを使って高速化されている
競技プログラミング分野で目にすることが度々ある

【仕組み】
CPythonのサブセットであるRPythonを使って実装されている
RPythonは制限付きのCPythonで実装されたPython処理系
JITコンパイルは何度も使われるコードを最適化するため、Pythonのコードでもかなり早く動かすことができる

【利点】
速度、メモリ使用量、サンドボックス、並列性で優れている
Pythonの標準ライブラリやサードパーティライブラリと互換性がある

pyenvでPyPyをインストールする
https://zenn.dev/3w36zj6/scraps/2b32292c31aec2

pypyのインストール
$ wget https://pypy.org/download.html
https://downloads.python.org/pypy/pypy3.11-v7.3.18-linux64.tar.bz2
bunzip2 -d pypy3.11-v7.3.18-linux64.tar bz2
tar xvf pypy3.11-v7.3.18-linux64.tar
$ sudo mv pypy3.11-v7.3.18-linux64 /usr/local/
$ cd /usr/local/pypy3.11-v7.3.18-linux64/bin
$ sudo ln -s /usr/local/pypy3.11-v7.3.18-linux64/bin/pypy /usr/bin/pypy

現在のpythonを確認

[suzuki@ip-172-31-14-193 Github]$ pyenv versions
  system
* 3.10.0 (set by /home/suzuki/Github/.python-version)
  pypy3.10-7.3.17

デフォルトのpythonをpypyにする

[suzuki@ip-172-31-14-193 Github]$ pyenv local pypy3.10-7.3.17
[suzuki@ip-172-31-14-193 Github]$ pyenv versions
  system
  3.10.0
* pypy3.10-7.3.17 (set by /home/suzuki/Github/.python-version)

確認

[suzuki@ip-172-31-14-193 Github]$ pypy -V
Python 3.10.14 (39dc8d3c85a7, Aug 27 2024, 14:32:27)
[PyPy 7.3.17 with GCC 10.2.1 20210130 (Red Hat 10.2.1-11)]
[suzuki@ip-172-31-14-193 Github]$

codon のインストール

codonの関連リンクを紹介しながら説明していきます。

あなたのPythonを100倍高速にする技術 / Codon入門
https://zenn.dev/turing_motors/articles/e23973714c3ecf

3行まとめ
高性能で簡単に扱えるPythonコンパイラ「Codon」
CodonはPythonコードをネイティブなマシンコードにコンパイル
Pythonとの互換性がありながら、CやC++に匹敵する高速化を実現
実際にPythonコードが100倍速くなることを検証
Codonの開発はGithub上で行われている

Github: codon
https://github.com/exaloop/codon

# codonのインストール
$ /bin/bash -c "$(curl -fsSL https://exaloop.io/install.sh)"
$ echo 'export PATH="$HOME/.codon/bin:$PATH"' >> ~/.bashrc
# 共有ライブラリを環境変数に設定します
$ echo 'export CODON_PYTHON=$PYENV_ROOT/versions/3.10.10/lib/libpython3.10.so' >> ~/.bashrc
$ source ~/.bashrc

codonの実行

元のpythonコード

def fib(n):
  # n未満のフィボナッチ数列を全てprintします
  a, b = 0, 1
  while a < n:
    print(a, end=' ')
    a, b = b, a+b
  print()
fib(1000)

2種類の実行方法があります。
runで実行すると実行ファイルを生成することなく実行します。

$ codon run fib.py
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

build で実行すると実行ファイルを生成します。実行するには./で実行します。

$ codon build fib.py
$ ./fib

さらに
-release で実行するとコードを最適化してコンパイルします。
結果高速化されます。

$ codon build  -release fib.py && ./fib
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

ここまではソースコードに全く手を入れることなく実行してきました。
pypyと同様に、codonも手を入れることなく動きますが、手を入れることによってもっともっと高速に実行することができます。

手を入れることなく動くのは、厳格なpythonコード表記で書かれている場合です。pythonは曖昧な言語なので、多少の間違いは良いように解釈して実行してくれます。codonはそういった曖昧さを厳格なソースに書き換えることで、ほぼC言語/C++言語と同等の速度でPythonコードを実行することができます。

次回からは実際のN-Queensソースコードを次から次へとcodon化して行きます。

ソースコード

今回の連載 python/pypy/codonのソースコードディレクトリはこちら
https://github.com/suzukiiichiro/N-Queens/tree/master/10Bit_Python

Nクイーン問題 過去記事アーカイブ

【過去記事アーカイブ】Nクイーン問題 過去記事一覧
https://suzukiiichiro.github.io/search/?keyword=Nクイーン問題
【Github】エイト・クイーンのソース置き場 BashもJavaもPythonも!
https://github.com/suzukiiichiro/N-Queens

Nクイーン問題(69)Python-codonで高速化 03Python_backTracking
https://suzukiiichiro.github.io/posts/2025-03-06-01-n-queens-suzuki/
Nクイーン問題(68)Python-codonで高速化 02Python_postFlag
https://suzukiiichiro.github.io/posts/2025-03-05-03-n-queens-suzuki/
Nクイーン問題(67)Python-codonで高速化 01Python_bluteForce"
https://suzukiiichiro.github.io/posts/2025-03-05-02-n-queens-suzuki/
Nクイーン問題(66)Python-codonで高速化
https://suzukiiichiro.github.io/posts/2025-03-05-01-n-queens-suzuki/
Nクイーン問題(65) N25を解決!事実上の日本一に
https://suzukiiichiro.github.io/posts/2024-04-25-01-n-queens-suzuki/
Nクイーン問題(64)第七章 並列処理 キャリーチェーン NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-05-n-queens-suzuki/
Nクイーン問題(63)第七章 並列処理 キャリーチェーン NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-05-n-queens-suzuki/
Nクイーン問題(62)第七章 並列処理 対称解除法 ビットボード NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-04-n-queens-suzuki/
Nクイーン問題(61)第七章 並列処理 対称解除法 ノードレイヤー NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-03-n-queens-suzuki/
Nクイーン問題(60)第七章 並列処理 ミラー NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-02-n-queens-suzuki/
Nクイーン問題(59)第七章 並列処理 ビットマップ NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-01-n-queens-suzuki/
Nクイーン問題(58)第六章 並列処理 pthread C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-09-n-queens-suzuki/
Nクイーン問題(57)第八章 キャリーチェーン C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-08-n-queens-suzuki/
Nクイーン問題(56)第八章 ミラー C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-06-n-queens-suzuki/
Nクイーン問題(55)第八章 ビットマップ C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-05-n-queens-suzuki/
Nクイーン問題(54)第八章 ビットマップ C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-04-n-queens-suzuki/
Nクイーン問題(53)第八章 配置フラグ C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-03-n-queens-suzuki/
Nクイーン問題(52)第八章 バックトラック C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-02-n-queens-suzuki/
Nクイーン問題(51)第八章 ブルートフォース C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-01-n-queens-suzuki/
Nクイーン問題(50)第七章 マルチプロセス Python編
https://suzukiiichiro.github.io/posts/2023-06-21-04-n-queens-suzuki/
Nクイーン問題(49)第七章 マルチスレッド Python編
https://suzukiiichiro.github.io/posts/2023-06-21-03-n-queens-suzuki/
Nクイーン問題(48)第七章 シングルスレッド Python編
https://suzukiiichiro.github.io/posts/2023-06-21-02-n-queens-suzuki/
Nクイーン問題(47)第七章 クラス Python編
https://suzukiiichiro.github.io/posts/2023-06-21-01-n-queens-suzuki/
Nクイーン問題(46)第七章 ステップNの実装 Python編
https://suzukiiichiro.github.io/posts/2023-06-16-02-n-queens-suzuki/
Nクイーン問題(45)第七章 キャリーチェーン Python編
https://suzukiiichiro.github.io/posts/2023-06-16-01-n-queens-suzuki/
Nクイーン問題(44)第七章 対象解除法 Python編
https://suzukiiichiro.github.io/posts/2023-06-14-02-n-queens-suzuki/
Nクイーン問題(43)第七章 ミラー Python編
https://suzukiiichiro.github.io/posts/2023-06-14-01-n-queens-suzuki/
Nクイーン問題(42)第七章 ビットマップ Python編
https://suzukiiichiro.github.io/posts/2023-06-13-05-n-queens-suzuki/
Nクイーン問題(41)第七章 配置フラグ Python編
https://suzukiiichiro.github.io/posts/2023-06-13-04-n-queens-suzuki/
Nクイーン問題(40)第七章 バックトラック Python編
https://suzukiiichiro.github.io/posts/2023-06-13-03-n-queens-suzuki/
Nクイーン問題(39)第七章 バックトラック準備編 Python編
https://suzukiiichiro.github.io/posts/2023-06-13-02-n-queens-suzuki/
Nクイーン問題(38)第七章 ブルートフォース Python編
https://suzukiiichiro.github.io/posts/2023-06-13-01-n-queens-suzuki/
Nクイーン問題(37)第六章 C言語移植 その17 pthread並列処理完成
https://suzukiiichiro.github.io/posts/2023-05-30-17-n-queens-suzuki/
Nクイーン問題(36)第六章 C言語移植 その16 pthreadの実装
https://suzukiiichiro.github.io/posts/2023-05-30-16-n-queens-suzuki/
Nクイーン問題(35)第六章 C言語移植 その15 pthread実装直前版完成
https://suzukiiichiro.github.io/posts/2023-05-30-15-n-queens-suzuki/
Nクイーン問題(34)第六章 C言語移植 その14
https://suzukiiichiro.github.io/posts/2023-05-30-14-n-queens-suzuki/
Nクイーン問題(33)第六章 C言語移植 その13
https://suzukiiichiro.github.io/posts/2023-05-30-13-n-queens-suzuki/
Nクイーン問題(32)第六章 C言語移植 その12
https://suzukiiichiro.github.io/posts/2023-05-30-12-n-queens-suzuki/
Nクイーン問題(31)第六章 C言語移植 その11
https://suzukiiichiro.github.io/posts/2023-05-30-11-n-queens-suzuki/
Nクイーン問題(30)第六章 C言語移植 その10
https://suzukiiichiro.github.io/posts/2023-05-30-10-n-queens-suzuki/
Nクイーン問題(29)第六章 C言語移植 その9
https://suzukiiichiro.github.io/posts/2023-05-30-09-n-queens-suzuki/
Nクイーン問題(28)第六章 C言語移植 その8
https://suzukiiichiro.github.io/posts/2023-05-30-08-n-queens-suzuki/
Nクイーン問題(27)第六章 C言語移植 その7
https://suzukiiichiro.github.io/posts/2023-05-30-07-n-queens-suzuki/
Nクイーン問題(26)第六章 C言語移植 その6
https://suzukiiichiro.github.io/posts/2023-05-30-06-n-queens-suzuki/
Nクイーン問題(25)第六章 C言語移植 その5
https://suzukiiichiro.github.io/posts/2023-05-30-05-n-queens-suzuki/
Nクイーン問題(24)第六章 C言語移植 その4
https://suzukiiichiro.github.io/posts/2023-05-30-04-n-queens-suzuki/
Nクイーン問題(23)第六章 C言語移植 その3
https://suzukiiichiro.github.io/posts/2023-05-30-03-n-queens-suzuki/
Nクイーン問題(22)第六章 C言語移植 その2
https://suzukiiichiro.github.io/posts/2023-05-30-02-n-queens-suzuki/
Nクイーン問題(21)第六章 C言語移植 その1
N-Queens問://suzukiiichiro.github.io/posts/2023-05-30-01-n-queens-suzuki/
Nクイーン問題(20)第五章 並列処理
https://suzukiiichiro.github.io/posts/2023-05-23-02-n-queens-suzuki/
Nクイーン問題(19)第五章 キャリーチェーン
https://suzukiiichiro.github.io/posts/2023-05-23-01-n-queens-suzuki/
Nクイーン問題(18)第四章 エイト・クイーンノスタルジー
https://suzukiiichiro.github.io/posts/2023-04-25-01-n-queens-suzuki/
Nクイーン問題(17)第四章 偉人のソースを読む「N24を発見 Jeff Somers」
https://suzukiiichiro.github.io/posts/2023-04-21-01-n-queens-suzuki/
Nクイーン問題(16)第三章 対象解除法 ソース解説
https://suzukiiichiro.github.io/posts/2023-04-18-01-n-queens-suzuki/
Nクイーン問題(15)第三章 対象解除法 ロジック解説
https://suzukiiichiro.github.io/posts/2023-04-13-02-nqueens-suzuki/
Nクイーン問題(14)第三章 ミラー
https://suzukiiichiro.github.io/posts/2023-04-13-01-nqueens-suzuki/
Nクイーン問題(13)第三章 ビットマップ
https://suzukiiichiro.github.io/posts/2023-04-05-01-nqueens-suzuki/
Nクイーン問題(12)第二章 まとめ
https://suzukiiichiro.github.io/posts/2023-03-17-02-n-queens-suzuki/
Nクイーン問題(11)第二章 配置フラグの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-17-01-n-queens-suzuki/
Nクイーン問題(10)第二章 バックトラックの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-16-01-n-queens-suzuki/
Nクイーン問題(9)第二章 ブルートフォースの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-14-01-n-queens-suzuki/
Nクイーン問題(8)第一章 まとめ
https://suzukiiichiro.github.io/posts/2023-03-09-01-n-queens-suzuki/
Nクイーン問題(7)第一章 ブルートフォース再び
https://suzukiiichiro.github.io/posts/2023-03-08-01-n-queens-suzuki/
Nクイーン問題(6)第一章 配置フラグ
https://suzukiiichiro.github.io/posts/2023-03-07-01-n-queens-suzuki/
Nクイーン問題(5)第一章 進捗表示テーブルの作成
https://suzukiiichiro.github.io/posts/2023-03-06-01-n-queens-suzuki/
Nクイーン問題(4)第一章 バックトラック
https://suzukiiichiro.github.io/posts/2023-02-21-01-n-queens-suzuki/
Nクイーン問題(3)第一章 バックトラック準備編
https://suzukiiichiro.github.io/posts/2023-02-14-03-n-queens-suzuki/
Nクイーン問題(2)第一章 ブルートフォース
https://suzukiiichiro.github.io/posts/2023-02-14-02-n-queens-suzuki/
Nクイーン問題(1)第一章 エイトクイーンについて
https://suzukiiichiro.github.io/posts/2023-02-14-01-n-queens-suzuki/

書籍の紹介

Nクイーン問題(67)Python-codonで高速化 01Python_bluteForce

Nクイーン問題(67)Python-codonで高速化 01Python_bluteForce

Nクイーン問題(65) N25を解決!事実上の日本一に

Nクイーン問題(65) N25を解決!事実上の日本一に