1

比較的単純な質問:
CPU バウンドのボトルネック メソッドを Python から C 拡張 (ほぼ同じアルゴリズムを実装) に変換すると、

  • 速度とパフォーマンスの向上はどの程度期待できますか?
  • それを決定する要因は何ですか?

更新: 人々は詳細の欠如に不満を持っているようでした. 私は主に、どのような要因が Python コードの一部を C で書き直すのに適した候補にするのかを理解しようとしていました (つまり、元の Python が CPU バウンドである場合、C に移植すると実際に速度が向上するのはいつでしょうか)。

詳細については、これが私が見ているコードです。基本的には、リストの 2 つのリスト (「列」のリスト、各列にはその列に入る可能性のある値が含まれています...基本的にはスキーマ) を取り、n 未満にすることが可能かどうかを確認する再帰的な方法です。 (通常は 1) 変更 (列に新しい値を追加する、新しい列を追加する、列を削除するなどの変更が行われる場合) 値のシーケンス (各列から 1 つの値) が存在するようにします。どちらのスキーマからでも構築できます。これは、文字列間の編集距離を計算するのと非常によく似ています。コードは次のとおりです。

def CheckMerge(self, schemai, schemaj, starti, startj, \
               changesLeft, path):
#        if starti == 0 and startj == 0:
#            print '\n'
#            print schemai.schema
#            print ''
#            print schemaj.schema
    if starti == len(schemai.schema) and startj == len(schemaj.schema):
        return (True, path)
    if starti < len(schemai.schema):
        icopy = schemai.schema[starti]
    else:
        icopy = []
    if startj < len(schemaj.schema):
        jcopy = schemaj.schema[startj]
    else:
        jcopy = []
    intersect = set(icopy).intersection(set(jcopy))
    intersect.discard('')
    if len(intersect) == 0:
        if starti < len(schemai.schema) and \
            ('' in schemai.schema[starti] or changesLeft > 0):

            if not '' in schemai.schema[starti]:
                changesLeft -= 1
            changesCopy = list(path)
            changesCopy.append('skipi')
            result,steps = self.CheckMerge(schemai, schemaj, starti+1, startj, \
                                     changesLeft, changesCopy)
            if result:
                return (result,steps)
            elif not '' in schemai.schema[starti]:
                changesLeft += 1

        if startj < len(schemaj.schema) and \
            ('' in schemaj.schema[startj] or changesLeft > 0):

            if not '' in schemaj.schema[startj]:
                changesLeft -= 1
            changesCopy = list(path)
            changesCopy.append('skipj')
            result,steps = self.CheckMerge(schemai, schemaj, starti, startj+1, \
                                     changesLeft, changesCopy)
            if result:
                return (result, steps)
            elif not '' in schemaj.schema[startj]:
                changesLeft += 1

        if changesLeft > 0:
            changesCopy = list(path)
            changesCopy.append('replace')
            changesLeft -= 1
            result,steps = self.CheckMerge(schemai, schemaj, starti+1, startj+1, \
                                     changesLeft, changesCopy)
            if result:
                return (result, steps)

        return (False, None)
    else:
        changesCopy = list(path)
        changesCopy.append('merge')
        result,steps = self.CheckMerge(schemai, schemaj, starti+1, startj+1, \
                                     changesLeft, changesCopy)
        if result:
            return (result, steps)
        else:
            return (False, None)
4

2 に答える 2

1

それはあなたのコードに完全に依存します。ハミング重みの計算、AES 暗号化の実行、CRC の計算、またはベクトル化可能なコードがある場合など、コードの一部がハードウェアでサポートされている場合、速度を向上させるハードウェア命令があり、 C コードではアクセスできますが、Python コードではアクセスできません。

于 2013-03-10T06:26:41.750 に答える
0

Python は非常に高速に実行されるため、Python 関数を C に変換するには、既に述べたハードウェアにアクセスするなど、明確な理由が必要です。しかし、ここには別の理由があります。

Python (C Python) には、Global Interpreter Lock (GIC) の問題があります。Python スレッドは同時に実行できず、一度に 1 つずつしか実行できません。したがって、GIC の問題によって制限されないスレッド固有のコードを C に入れることができます。

一般に、Python コードが遅いと思われ、投稿で述べたような特定の理由がない場合は、Python に見られるリスト内包表記やその他の機能など、より Python らしいコーディング規則に適応する必要があるかもしれません。他の言語はそれほど多くありません。

私の最後のコメントは、コード サンプルを反映したものではありません。代わりに、多くの Python プレゼンテーションを聞いて学んだ一般的な知恵として提供しています。

于 2013-03-10T19:58:53.343 に答える