実現したいこと
- Main.py, SubA.py, SubB.pyをそれぞれコンパイル
- Main.pyからSubAとSubBを呼び出し、インスタンス化
- SubAにSubBを与える
- SubAを実行し、結果をSubBのインスタンス変数から読み込みprint
データを読み込んだり、外部と通信するSubB.pyと、
特定のアルゴリズムで処理を行うSubA.pyを、
Mein.pyから呼び出しています。
用途によって渡すモジュールや処理するアルゴリズムを切り替えたいため、このような実装になっております。
純粋なPythonではうまく動きますが、処理が低速なため、Cythonを使用しようと思いましたが、エラーが発生してしまい、解決方法が分かりません・・・
オーバーヘッドを抑えつつ、エラーを解消する方法がありましたら、ご教示ください。
環境
Python 3.6.8
Cython 0.29.14
Cythonはpure Pythonモードを使用しています。
該当のソースコード
同一のディレクトリに以下のファイルがあり、コンパイル後init.pyを実行します。
init.py/Main.py/SubA.py/SubB.py/setup.py
コマンド:
python setup.py build_ext --inplace
initpy
1from Main import * 2import array 3 4Main(array.array("q", range(100)))
Mainpy
1import cython 2from SubA import * 3from SubB import * 4 5 6class Main: 7 data = cython.declare(cython.longlong[:]) 8 9 @cython.locals(data=cython.longlong[:], result=cython.longlong) 10 def __init__(self, data): 11 self.data = data 12 subB = SubB(data) 13 subA = SubA(subB) 14 subA.start() 15 result = subA.result 16 print(result)
SubApy
1import cython 2 3@cython.cclass 4class SubA: 5 result = cython.declare(cython.longlong) 6 7 def __init__(self, subB): 8 self.subB = subB 9 self.result = 0 10 11 @cython.cfunc 12 def start(self): 13 while self.subB.flag: 14 self.result += self.subB.get() 15 self.subB.add() 16
SubBpy
1import cython 2 3@cython.cclass 4class SubB: 5 data = cython.declare(cython.longlong[:]) 6 i = cython.declare(cython.int) 7 len = cython.declare(cython.int) 8 flag = cython.declare(cython.bint, visibility='public') 9 10 @cython.locals(data=cython.longlong[:]) 11 def __init__(self, data): 12 self.data = data 13 self.i = 0 14 self.len = len(data) 15 self.flag = True 16 17 @cython.cfunc 18 def add(self): 19 self.i += 1 20 if self.i >= self.len: 21 self.flag = False 22 23 @cython.cfunc 24 @cython.returns(cython.longlong) 25 def get(self): 26 if self.i >= self.len: 27 return 0 28 return self.data[self.i] 29
setuppy
1from distutils.core import setup 2from distutils.extension import Extension 3from Cython.Distutils import build_ext 4 5files = ["SubA", "SubB", "Main"] 6 7 8for f in files: 9 ext_modules = [Extension(f, [f + ".py"])] 10 11 setup( 12 name=f, 13 cmdclass={'build_ext': build_ext}, 14 ext_modules=ext_modules 15 ) 16
発生しているエラー
console
1Traceback (most recent call last): 2 File "C:/Call.py", line 4, in <module> 3 Main(array.array("q", range(100))) 4 File "Main.py", line 13, in Main.Main.__init__ 5 subA = SubA(subB) 6 File "SubA.py", line 9, in SubA.SubA.__init__ 7 self.subB = subB 8AttributeError: 'SubA.SubA' object has no attribute 'subB'
SubA側の@cython.cclassを取り除く事により、エラーなく動作しますが、高速化は4倍程度となります。
50~90倍程度の高速化を目標にしています。
以上、よろしくおねがいします
あなたの回答
tips
プレビュー