2016-09-17 13 views
0

私はCythonを使用して関数をCにコンパイルしていますが、 "Unreachable code"警告を受け取ります。 pyxファイルを調べると、私はそれがどうやって得たか分かりませんが、さらにreturn locals()が表示されます。cython.inlineを使用しているときに到達不能なコード

コードがcython.inlineによって生成されます。

cython.inline('return a * b + c if a > b else 0.0', a=1, b=2, c=3) 

次のようになりますPYXファイル生成する:私はこの機能をcythonizingていた理由は、パフォーマンスを向上させることです

def __invoke(double a, double b, double c): 
    return a * b + c if a > b^2 else 0.0 
    return locals() 

を。上記の機能は単純化されていますが、基本的な要素は同じです。インライン関数は配列numpyを使用していないことに注意してください。誰かが表現を評価するより速い方法を考えることができれば、私はそれを試してみてうれしく思います(元の表現の構文は少し異なりますが、私はそれをどのような形式にでもコンパイルできます)。

とにかく、この質問の主なポイントは、理由と追加のreturnステートメントが追加され、それを削除する方法を理解することです。

更新

これは私がcython.inlineコール(@DavidWとの会話を指し)から気づいたオーバーヘッドです。

enter image description here

答えて

1

は、私はそれはあなたがreturn文を追加しない場合は、バックローカル変数の辞書を取得するようだと思います。例えば。

cython.inline('''x = a*b 
y = b+c 
z = a-c 
''', a=1, b=2, c=3) 

xy、およびzの辞書をあなたに戻って得られます。明らかに、それはあなた自身で手動で行うことができるので少し不必要ですが、いくつかのユースケースが簡単になります(削除すると既存のコードとの互換性が損なわれます)。

Cythonは、コンパイルするすべての末尾にreturn locals()を追加することでこれらの機能を実現します。 source codeで見つけることができます。

私はあなたがそれを取り除くことができるとは思わないが、それはあなたに何も(コンパイラの警告を除いて)費用がかかりません - それはコードが到達できないように到達できないことはCコンパイラにとって明らかです。


パフォーマンスの向上に関する二次質問に答えるには、このような計算はおそらく繰り返し呼び出されると問題になるでしょうか?私はCythonでループを手に入れようとしていますが、もしそうでなければ、あなたが多くを得れば驚くでしょう。

+0

ありがとうございます。私はこれのためのソースコードをチェックすることを忘れました...はい、この関数は繰り返し呼び出されます。私はそれをcythonizingですばらしいスピードアップに気づいたが、Cythonのいくつかの呼び出しから、少しでもオーバーヘッドがあった。これは、一度コンパイルされても関数がキャッシュされていてもうまくいくだろう。私はそれがインライン展開かCythonが動作するかどうかによるのだろうかと思います。コールは異なる場所で発生し、実際のループから遠く離れているため(一部の配列データのカーネル機能とは異なります)、ループを組み込むことはできません。 – orange

+0

関連するコールのrunnakerunスクリーンショットで質問を更新しました。 – orange

+0

@orange私は、キャッシュされているかどうかを調べるために大抵のことをしていると思います(回答にgithubリンクのコードを見てください - それはかなり複雑です)。 pyxファイルで1行の関数を作成し、それを普通にコンパイルした方がパフォーマンスが向上します。関数が呼び出されると、オーバーヘッドチェックの型はまだありますが、それは少なくなります。 – DavidW

関連する問題