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

ソースコード

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

インストールなどの構築はこちら

Nクイーン問題(66) Python-codonで高速化
https://suzukiiichiro.github.io/posts/2025-03-05-01-n-queens-suzuki/

配置フラグ python/pypy/codonで速度比較

以下のソースコードをpythonで実行してみます
ちなみに以下のソースコードはcodon対応したソースコードです。
codon対応したソースコードは、pythonでもpypyでも問題なく動作するところがcodonのすごいところです。

# pypyを使う場合はコメントを解除
# pypyで再帰が高速化できる
import pypyjit
pypyjit.set_param('max_unroll_recursion=-1')

class NQueens02:
  size:int
  count:int
  aboard:list[int]
  fa:list[int]
  def __init__(self):
    self.size=8;
    self.count=0;
    self.aboard=[0 for i in range(self.size)];
    self.fa=[0 for i in range(self.size)];
  def printout(self):
    self.count+=1;
    print(self.count,end=": ");
    for i in range(self.size):
      print(self.aboard[i],end="");
    print("");
  def nqueens(self,row:int):
    if row==self.size-1:
      self.printout();
    else:
      for i in range(self.size):
        self.aboard[row]=i;
        if self.fa[i]==0:
          self.fa[i]=1;
          self.nqueens(row+1);
          self.fa[i]=0;

# 2.配置フラグ
# $ python <filename>
# $ pypy <fileName>
# $ codon build -release <filename>
if __name__ == '__main__':
  NQueens02().nqueens(0);

pythonで実行する場合はソースコード冒頭の import 行と pypyjit 行をコメントアウトします

# pypyを使う場合はコメントを解除
# pypyで再帰が高速化できる
# import pypyjit # コメントアウト
# pypyjit.set_param('max_unroll_recursion=-1') # コメントアウト

pythonで実行

$time python 02Python_postFlag.py
:
:
0315: 76543010
40316: 76543020
40317: 76543100
40318: 76543120
40319: 76543200
40320: 76543210

real    0m0.919s
user    0m0.546s
sys     0m0.179s

pypyで実行

pypyで実行する場合はソースコード冒頭の import 行と pypyjit 行をコメント「解除」(活かす)します。さらに高速になります。この2行はpypyで実行するときのみ必要となります。よってpython/codonで実行する場合は、コメントアウトしないとエラーとなります。

# pypyを使う場合はコメントを解除
# pypyで再帰が高速化できる
import pypyjit # コメント解除
pypyjit.set_param('max_unroll_recursion=-1') # コメント解除
$time pypy 02Python_postFlag.py
:
:
40315: 76543010
40316: 76543020
40317: 76543100
40318: 76543120
40319: 76543200
40320: 76543210

real    0m1.286s
user    0m0.870s
sys     0m0.203s

codonで実行

codonで実行する場合はpython同様、以下の import 行と pypyjit 行をコメントアウトします

# pypyを使う場合はコメントを解除
# pypyで再帰が高速化できる
# import pypyjit # コメントアウト
# pypyjit.set_param('max_unroll_recursion=-1') # コメントアウト
$time codon build -release 02Python_postFlag.py && ./02Python_postFlag
:
:
40315: 76543010
40316: 76543020
40317: 76543100
40318: 76543120
40319: 76543200
40320: 76543210

real    0m0.280s
user    0m0.337s
sys     0m0.113s

実行結果

python real    0m0.919s
pypy   real    0m1.286s
codon  real    0m0.280s

Nが小さいのであっという間に終わってしまいますが、次の章からはそういうわけには行きません。
あっという間に終わるのはここまでです。

では早速ソースコードのcodon化を進めていきます。
前の章でも説明しましたが、

1.ソースコードの__main__は以下のようにclassを利用して呼び出す方が高速です。

if __name__ == '__main__':    # 高速化にはここが重要
  NQueens01().nqueens(0)

ソースの本体はclass化しましょう。

class NQueens01:
  :
  :
  def nqueens(self,row:int):
    :
    :
if __name__ == '__main__':
  NQueens01().nqueens(0)

グローバル変数はゼロにすべきですが、説明も必要なのでここはあえてグローバル変数を用いています。
グローバル変数は、初期化する必要はありません。その代わり型を明示的に書く必要があります。

  size:int          # int型のsizeを宣言

グローバル変数の初期化は__init()__(self):で行います。

  def __init__(self):
    self.size=8
    self.aboard=[0 for i in range(self.size)]
    self.count=0

__init__(self):関数の中で、グローバル変数に初期値を代入します。
グローバル変数はselfをつけてアクセスします。

def nqueens(self,row:int): で関数を宣言しています。
__main__から呼び出されていますが、0を渡されていますね。
受け取る nqueens()では

  def nqueens(self,row):

ではなく

  def nqueens(self,row:int):

と、書いて、__main__から呼び出されたnqueens()にわたす0は、rowという変数に渡されています。
row:intと明示的に数値であることが明記されています。これがcodonの厳格な型付けとなります。

class内で宣言する関数の第一パラメータは、暗黙的に必ずselfとなります。
関数パラメータで渡されたrowは関数内でself.rowと書く必要はありません。
関数パラメータはrowとして使うことができます。
その代わり、グローバル変数を使うとき、他の関数を呼び出すときは以下のようにself.を付ける必要があります。

  def nqueens(self,row:int):
    if row is self.size:
      self.printout();
    else:
      for i in range(self.size):
        self.aboard[row]=i;
        self.nqueens(row+1);

包括表記を多用しましょう
可読性が極端に低くなるほどに多用するのはどうかと思います。
が、包括表記に置き換えることで劇的に高速化します。
以下のコードは aboard fa ともにsize分を0で配列を初期化します

    self.aboard=[0 for i in range(self.size)];
    # aboard=[0,0,0,0,0,0,0,0]
    self.fa=[0 for i in range(self.size)];
    # fa=[0,0,0,0,0,0,0,0]

あと一点。リストの宣言はリテラル変数とは少し異なります。
この明示的な書き方は、関数パラメータの書き方も同様となります。

  リスト名:list[int]

と、覚えてしまえば良いと思います。

  aboard:list[int]
  fa:list[int]

では、ソースコードはこういうふうになります。

# pypyを使う場合はコメントを解除
# pypyで再帰が高速化できる
# import pypyjit
# pypyjit.set_param('max_unroll_recursion=-1')

class NQueens02:
  size:int
  count:int
  aboard:list[int]
  fa:list[int]
  def __init__(self):
    self.size=8;
    self.count=0;
    self.aboard=[0 for i in range(self.size)];
    self.fa=[0 for i in range(self.size)];
  def printout(self):
    self.count+=1;
    print(self.count,end=": ");
    for i in range(self.size):
      print(self.aboard[i],end="");
    print("");
  def nqueens(self,row:int):
    if row==self.size-1:
      self.printout();
    else:
      for i in range(self.size):
        self.aboard[row]=i;
        if self.fa[i]==0:
          self.fa[i]=1;
          self.nqueens(row+1);
          self.fa[i]=0;

# 2.配置フラグ
# $ python <filename>
# $ pypy <fileName>
# $ codon build -release <filename>
if __name__ == '__main__':
  NQueens02().nqueens(0);

実行は以下のとおりです。

$ codon build -release 02Python_postFlag.py && time 02Python_postFlag

実行結果は冒頭を省略すると以下のようになります。

:
:
40305: 76541200
40306: 76541230
40307: 76541300
40308: 76541320
40309: 76542010
40310: 76542030
40311: 76542100
40312: 76542130
40313: 76542300
40314: 76542310
40315: 76543010
40316: 76543020
40317: 76543100
40318: 76543120
40319: 76543200
40320: 76543210

real    0m0.280s
user    0m0.337s
sys     0m0.113s

次の章では、バックトラックの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クイーン問題(69)Python-codonで高速化 03Python_backTracking

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

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

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