私はアルゴリズムを研究していて、Javaプログラムを教科書からPythonに移植することにしました。これは、特に小さなプログラムの場合や演習として、Javaのオーバーヘッドが嫌いなためです。
アルゴリズム自体は非常に単純です。ブルートフォースのような方法で、配列からすべてのトリプレットを取り出し、合計がゼロになるトリプレットの数をカウントします(例:[-2,7、-5])。
public static int count(int[] a) {
int N = a.length;
int cnt = 0;
for (int i = 0; i < N; i++) {
for (int j = i+1; j < N; j++) {
for (int k = j+1; k < N; k++) {
if (a[i] + a[j] + a[k] == 0) {
cnt++;
}
}
}
}
return cnt;
}
私はそれをに移植しました:
def count(a):
cnt = 0
ln = len(a)
for i in xrange(0,ln):
for j in xrange(i + 1,ln):
for k in xrange(j + 1,ln):
if a[i] + a[j] + a[k] == 0:
cnt+=1
return cnt
現在、これらの関数だけを測定しています。
java : array of 2000 elements --> 3 seconds
python : array of 2000 elements --> 2 minutes, 19 seconds
UPDATE
python (pypy) : array of 2000 elements --> 4 seconds ( :-) )
もちろん、これは良いアルゴリズムではありません。ここと教科書の両方で表示されます。私は以前にJavaとPythonの両方でプログラミングを行ったことがありますが、この大きな違いに気づいていませんでした。
質問は要約すると、これをどのように克服するのでしょうか。すなわち :
- このコードは良い移植ですか、それとも些細なことを見逃していますか?
- たとえば、別のランタイムJythonに切り替えることは解決策ですか?コードベースをEclipseに保持し、インタープリター(コンパイラー)を追加するのは簡単ですか?それとも、別のインタプリタ/コンパイラに切り替えると、状況が少しだけ良くなるだけですか?
現在、Windows7でPython2.7.3とJava1.732ibtsを使用しています。
私は、Java / pythonのパフォーマンスについて、SOについて同様の質問があることを知っていますが、Pythonのランタイム環境が異なるなどの回答は、現時点では役に立ちません。
私が知りたいのは、これらのランタイムのいくつかがこの巨大なギャップを埋めることができ、epxloringする価値があるかどうかです。
アップデート :
私はpypyをインストールしましたが、今ではその違いは非常に大きいです...
更新2:
私が気付いたいくつかの非常に興味深いこと:ここでの回答のisliceメソッドは、「通常の」Pythonでは高速ですが、pypyでははるかに低速です。それでも、このアルゴリズムで通常のループやisliceを使用していても、pypyを使用するとはるかに高速なままです。
Bakuriuが発言で気づいたように、ランタイム環境は非常に重要ですが、このアルゴリズムのランタイム環境が高速であると、どのアルゴリズムでも必ずしも高速であるとは限りません...