2

一部の C コードを Python コードに置き換え、pypy をインタープリターとして使用することを検討しています。コードは多くのリスト/辞書操作を行います。したがって、pypy と CI のパフォーマンスについて漠然とした考えを得るために、ソート アルゴリズムを作成しています。すべての読み取り関数をテストするために、Python と C++ の両方でバブル ソートを作成しました。もちろん、CPython は 6.468 秒、pypy は 0.366 秒、C++ は 0.229 秒かかります。その後、C++ コードの -O3 を忘れていたことを思い出し、時間が 0.042 秒になりました。32768 データセットの場合、-O3 を指定した C++ はわずか 2.588 秒で、pypy は 19.65 秒です。Pythonコードを高速化するためにできることはありますか(もちろん、より良いソートアルゴリズムを使用する以外に)、またはpypy(フラグなど)を使用する方法はありますか?

Python コード (read_nums モジュールは、時間は簡単なので省略: 32768 データセットで 0.036 秒):

import read_nums
import sys

nums = read_nums.read_nums(sys.argv[1])

done = False

while not done:
    done = True

    for i in range(len(nums)-1):
        if nums[i] > nums[i+1]:
            nums[i], nums[i+1] = nums[i+1], nums[i]
            done = False

$ time pypy-c2.0 bubble_sort.py test_32768_1.nums   
real    0m20.199s
user    0m20.189s
sys     0m0.009s

C コード (read_nums 関数は、時間がかからないため省略されています: 0.017 秒):

#include <iostream>
#include "read_nums.h"

int main(int argc, char** argv)
{
    std::vector<int> nums;
    int count, i, tmp;
    bool done;

    if(argc < 2)
    {
        std::cout << "Usage: " << argv[0] << " filename" << std::endl;
        return 1;
    }

    count = read_nums(argv[1], nums);

    done = false;

    while(!done)
    {
        done = true;

        for(i=0; i<count-1; ++i)
        {
            if(nums[i] > nums[i+1])
            {
                tmp = nums[i];
                nums[i] = nums[i+1];
                nums[i+1] = tmp;
                done = false;
            }
        }
    }

    for(i=0; i<count; ++i)
    {
        std::cout << nums[i] << ", ";
    }

    return 0;
}

$ time ./bubble_sort test_32768_1.nums > /dev/null  
real    0m2.587s
user    0m2.586s
sys     0m0.001s

PS最初の段落で与えられた数字のいくつかは、最初に得た数字であるため、当時の数字とは少し異なります。

さらなる改良:

  • range の代わりに xrange を試してみたところ、実行時間は 16.370 秒になりました。
  • コードを関数の最初done = Falseから最後done = Falseに移動し、速度は 8.771 ~ 8.834 秒になりました。
4

1 に答える 1

3

この質問に答える最も適切な方法は、C、CPython、および PyPy の速度が一定の要因で異なるわけではないことに注意することです。最も重要なことは、何が行われ、どのように記述されているかに依存します。たとえば、「同等の」Python コードが自然に辞書を使用するときに、C コードが配列のウォーキングなどの単純なことを行っている場合、配列が十分に長い場合、Python の実装は C よりも高速です。もちろん、これはほとんどの実際の例には当てはまりませんが、同じ議論がより少ない範囲で適用されます. C で書かれたプログラム、または Python で書き直されて CPython または PyPy で実行されているプログラムの相対速度を予測する万能の方法はありません。

明らかに、これらの相対速度に関するガイドラインがあります。小さなアルゴリズムの例では、PyPy の速度が "gcc -O0" の速度に近づくと予想できます。あなたの例では、「わずか」1.6倍遅いです。10% または 30% 高速化するために、最適化を支援したり、PyPy に欠けている最適化を見つけたりすることさえできます。しかし、これは実際のプログラムとは何の関係もない小さな例です。上記の理由により、ここで得られる速度は、最終的に得られる速度と漠然としか関連していません.

私が言えることは、コードを明確にするために C から Python にコードを書き直すことです。特に、C が複雑になりすぎて開発が進まなくなった場合は、長期的には明らかに勝利です。その一部を C でもう一度書き直します。ここでの PyPy の目標は、その必要性を減らすことです。もはや誰も C を必要としないと言えばいいのですが、それは真実ではありません。:-)

于 2013-03-28T17:34:52.263 に答える