2016-07-19 3 views
4

프로젝트 오일러의 일부 문제를 해결하고 문제 10에 대해 동일한 기능을 작성했습니다 ...파이썬이이 인스턴스에서 C보다 훨씬 느린 이유는 무엇입니까?

저를 놀라게하는 것은 파이썬 솔루션이 약 283 초가 걸리는 동안 C 솔루션이 약 4 초 만에 실행된다는 것입니다. 나는 왜 C 구현이 파이썬 구현보다 훨씬 빠르다는 것을 나 자신에게 설명하려고 고심하고있다. 실제로 그렇게하는 것은 실제로 무엇인가?

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()'를 사용해 보거나 파이썬 3으로 전환하십시오. 여기서'range()'는 느린 반복자입니다. –

+0

정적 유형 선언과 아마도 메모리가 비효율적 인 반복기를 사용하는 것과 파이썬에서 생성기를 사용하는 것 – Dan

+1

'div'는 파이썬 코드에서 float이지만'sqrtDiv'는 C 코드에서 int입니다. –

답변

2

그것은 CPython의 (구현) 즉이 경우 느린입니다, 반드시 파이썬을하지. CPython은 컴파일 된 C 코드보다 거의 항상 느린 바이트 코드를 해석해야합니다. 동일한 C 코드보다 더 많은 작업을 수행합니다. 이론적으로는 sqrt을 호출 할 때마다 알려진 주소를 호출하는 대신 해당 기능을 조회해야합니다.

파이썬과 비슷한 속도를 원하면 유형에 소스를 주석으로 추가하고 Cython으로 컴파일하거나 Pypy로 실행하여 일부 JIT 성능을 시험해 볼 수 있습니다.

관련 문제