Niezwykła różnica prędkości między Pythonem a C ++

Niedawno napisałem krótki algorytm do obliczeniaszczęśliwe liczby w Pythonie. Program pozwala wybrać górną granicę i określi wszystkie szczęśliwe liczby poniżej. Dla porównania prędkości postanowiłem zrobić najbardziej bezpośrednie tłumaczenie algorytmu, którego znałem, z python na c ++.

Co zaskakujące, wersja c ++ działa znacznie wolniej niż wersja Pythona. Dokładne testy prędkości pomiędzy czasami wykonania w celu wykrycia pierwszych 10 000 szczęśliwych liczb wskazują, że program Pythona działa średnio w 0,59 sekundy, a wersja c ++ działa średnio w 8,5 sekundy.

Przypisałbym tę różnicę prędkości temu, że musiałem napisać funkcje pomocnicze dla części obliczeń (na przykład określając, czy element jest w liście / tablicy / wektorze) w wersji c ++, która była już wbudowana w język python .

Po pierwsze, czy jest to prawdziwy powód tak absurdalnej różnicy prędkości, a po drugie, jak mogę zmienić wersję c ++, aby była wykonywana szybciej niż wersja Pythona (tak powinno być, moim zdaniem).

Dwa fragmenty kodu z testowaniem prędkości są tutaj:Wersja Pythona, Wersja C ++. Dzięki za pomoc.

#include <iostream>
#include <vector>
#include <string>
#include <ctime>
#include <windows.h>

using namespace std;

bool inVector(int inQuestion, vector<int> known);
int sum(vector<int> given);
int pow(int given, int power);
void calcMain(int upperBound);

int main()
{
    while(true)
    {
        int upperBound;
        cout << "Pick an upper bound: ";
        cin >> upperBound;
        long start, end;
        start = GetTickCount();
        calcMain(upperBound);
        end = GetTickCount();
        double seconds = (double)(end-start) / 1000.0;
        cout << seconds << " seconds." << endl << endl;
    }
    return 0;
}

void calcMain(int upperBound)
{
    vector<int> known;
    for(int i = 0; i <= upperBound; i++)
    {
        bool next = false;
        int current = i;
        vector<int> history;
        while(!next)
        {
            char* buffer = new char[10];
            itoa(current, buffer, 10);
            string digits = buffer;
            delete buffer;
            vector<int> squares;
            for(int j = 0; j < digits.size(); j++)
            {
                char charDigit = digits[j];
                int digit = atoi(&charDigit);
                int square = pow(digit, 2);
                squares.push_back(square);
            }
            int squaresum = sum(squares);
            current = squaresum;
            if(inVector(current, history))
            {
                next = true;
                if(current == 1)
                {
                    known.push_back(i);
                    //cout << i << "\t";
                }
            }
            history.push_back(current);
        }
    }
    //cout << "\n\n";
}

bool inVector(int inQuestion, vector<int> known)
{
    for(vector<int>::iterator it = known.begin(); it != known.end(); it++)
        if(*it == inQuestion)
            return true;
    return false;
}

int sum(vector<int> given)
{
    int sum = 0;
    for(vector<int>::iterator it = given.begin(); it != given.end(); it++)
        sum += *it;
    return sum;
}

int pow(int given, int power)
{
    int original = given;
    int current = given;
    for(int i = 0; i < power-1; i++)
        current *= original;
    return current;
}
#!/usr/bin/env python

import timeit

upperBound = 0

def calcMain():
    known = []
    for i in range(0,upperBound+1):
        next = False
        current = i
        history = []
        while not next:
            digits = str(current)
            squares = [pow(int(digit), 2) for digit in digits]
            squaresum = sum(squares)
            current = squaresum
            if current in history:
                next = True
                if current == 1:
                    known.append(i)
                    ##print i, "\t",
            history.append(current)
    ##print "\nend"

while True:    
    upperBound = input("Pick an upper bound: ")
    result = timeit.Timer(calcMain).timeit(1)
    print result, "seconds.\n"

questionAnswers(17)

yourAnswerToTheQuestion