2016-07-19 8 views
4

私を驚かせる事がPythonの溶液を約283秒かかりながら、Cの溶液を約4秒で走るということです...この場合、PythonがCよりも非常に遅い理由は何ですか?

を私はプロジェクトのオイラーにいくつかの問題を解決して、私は、問題10のために、同一の機能を書きました。私は、なぜCの実装がPythonの実装よりもずっと速いのか、自分自身に説明するのに苦労しています。

C:

#include <stdio.h> 
#include <time.h> 
#include <math.h> 

int is_prime(int num) 
{ 
    int sqrtDiv = lround(sqrt(num)); 
    while (sqrtDiv > 1) { 
     if (num % sqrtDiv == 0) { 
      return(0); 
     } else { 
      sqrtDiv--; 
     } 
    } 
    return(1); 
} 

int main() 
{ 
    clock_t start = clock(); 

    long sum = 0; 
    for (int i = 2; i < 2000000; i++) { 
     if (is_prime(i)) { 
      sum += i; 
     } 
    } 
    printf("Sum of primes below 2,000,000 is: %ld\n", sum); 

    clock_t end = clock(); 
    double time_elapsed_in_seconds = (end - start)/(double)CLOCKS_PER_SEC; 
    printf("Finished in %f seconds.\n", time_elapsed_in_seconds); 
} 

パイソン:

from math import sqrt 
import time 


def is_prime(num): 
    div = round(sqrt(num)) 
    while div > 1: 
     if num % div == 0: 
      return False 
     div -= 1 
    return True 

start_time = time.clock() 

tsum = 0 
for i in range(2, 2000000): 
    if is_prime(i): 
     tsum += i 

print tsum 
print('finished in:', time.clock() - start_time, 'seconds') 
+10

Python 2.7を使用している場合、 'range(2、2000000)'は実際に約2000000の整数のメモリ内リストを構築します。代わりに 'xrange()'を試してみるか、 'range()'が遅延イテレータであるPython 3に切り替えてください。 –

+0

静的型の宣言とメモリ非効率なイテレータとジェネレータをPythonで使用する場合 – Dan

+1

'div'はPythonコードではfloatですが、' sqrtDiv'はCコードではintです。 –

答えて

2

必ずしもPYTHONない、すなわち、この場合に遅いCPythonの(実装)です。 CPythonは、バイトコードを解釈する必要があります。バイトコードは、コンパイルされたCコードよりもほとんど常に遅くなります。これは単に同等のCコードより多くのことを行います。理論的には、例えば、sqrtへの各呼び出しは、既知のアドレスへの呼び出しではなく、その機能を参照する必要があります。

Pythonと同等のスピードが必要な場合は、タイプにソースを注釈付けしたり、Cythonでコンパイルしたり、PypyでいくつかのJITパフォーマンスを試してみてください。

関連する問題