一部の 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 秒になりました。