12

数週間前、私は Python で書かれた関数の速度を上げることについて質問しました。その時、TryPyPy は Cython を使用する可能性に注目しました。彼は親切にも、そのコード スニペットを Cythonize する方法の例を示してくれました。以下のコードで同じことを行い、変数の型を宣言することでどれだけ速くできるかを確認したいと思います。それに関連していくつか質問があります。cython.org のチュートリアルを見ましたが、まだいくつか質問があります。それらは密接に関連しています。

  1. C はまったくわかりません。Cython を使用して変数の型を宣言するには、どの部分を学ぶ必要がありますか?
  2. Pythonのリストとタプルに対応するCの型は何ですか? たとえばdouble、Cython for floatin Python で使用できます。リストはどうすればいいですか? 一般に、特定の Python 型に対応する C 型はどこにありますか。

以下のコードを Cythonize する方法の例は、本当に役に立ちます。変数の型に関する情報を提供するコードにコメントを挿入しました。

class Some_class(object):
    ** Other attributes and functions **
    def update_awareness_status(self, this_var, timePd):
        '''Inputs: this_var (type: float)
           timePd (type: int)
           Output: None'''

        max_number = len(self.possibilities)
        # self.possibilities is a list of tuples.
        # Each tuple is a pair of person objects. 

        k = int(math.ceil(0.3 * max_number))
        actual_number = random.choice(range(k))
        chosen_possibilities = random.sample(self.possibilities, 
                                         actual_number)
        if len(chosen_possibilities) > 0:
            # chosen_possibilities is a list of tuples, each tuple is a pair
            # of person objects. I have included the code for the Person class
            # below.
            for p1,p2 in chosen_possibilities:

                # awareness_status is a tuple (float, int)
                if p1.awareness_status[1] < p2.awareness_status[1]:                   
                    if p1.value > p2.awareness_status[0]:
                        p1.awareness_status = (this_var, timePd)
                    else:
                        p1.awareness_status = p2.awareness_status
                elif p1.awareness_status[1] > p2.awareness_status[1]:
                    if p2.value > p1.awareness_status[0]:
                        p2.awareness_status = (price, timePd)
                    else:
                        p2.awareness_status = p1.awareness_status
                else:
                    pass     

class Person(object):                                         
    def __init__(self,id, value):
        self.value = value
        self.id = id
        self.max_val = 50000
        ## Initial awareness status.          
        self.awarenessStatus = (self.max_val, -1)
4

2 に答える 2

1

C はリストの概念を直接には知りません。基本的なデータ型はint( charshortlong)、float/ double(これらはすべて Python への非常に単純なマッピングを持っています) とポインターです。ポインターの概念が初めての場合は、Wikipedia:ポインターを参照してください。

ポインターは、場合によってはタプル/配列の置換として使用できます。文字のポインターは、すべての文字列のベースです。整数の配列があるとします。次に、それを開始アドレスを持つ連続したメモリのチャンクとして格納し、型 ( int) を定義し、それがポインター ( *)であることを定義します。

cdef int * array;

これで、次のように配列の各要素にアクセスできます。

array[0] = 1

ただし、メモリを割り当てる必要があり (たとえば、 を使用malloc)、高度なインデックス作成は機能しません (たとえばarray[-1]、メモリ内のランダム データになります。これは、予約されたスペースの幅を超えるインデックスにも適用されます)。

より複雑な型は C に直接マップされませんが、多くの場合、Python 型を必要としない可能性のある何かを実行する C の方法があります (たとえば、for ループは範囲配列/反復子を必要としません)。

お気付きのように、適切な cython コードを作成するには C に関するより詳細な知識が必要です。そのため、チュートリアルに進むことが次のステップとして最適です。

于 2011-02-02T21:18:13.833 に答える