在阅读我的文章之前,请考虑我对C和C++都是新的。
我主要是托管代码开发人员。
我有两段相同的代码(或者至少我相信这一点)。
C中的一个,C++中的一个。
代码基本上检查这个数字是否是一个素数,如果是,它将把它存储在一个容器中。
C++
主.cpp

#include <iostream>
#include <vector>
#include <time.h>

static bool isPrime(const int& number) {

    if((number & 1) == 0) {
        if(number == 2)
            return true;
        else
            return false;
    }

    for(int i = 3; (i * i) <= number; i++) {

        if((number % i) == 0)
            return false;
    }

    return number != 1;
}

int main(int argc, const char * argv[]) {

    std::vector<int> vector;
    clock_t start = clock();
    for(int i = 0; i < 30000000; i++) {

        if(isPrime(i))
            vector.push_back(i);
    }
    clock_t end = clock();
    clock_t seconds = (end - start) / CLOCKS_PER_SEC;
    std::cout << "done after " << seconds << " seconds " << std::endl;

    return 0;
}

C类
向量c
#include <stdlib.h>


typedef struct vector_class {
    void(*push_back)(struct vector_class *vector_instance, const int *data);
    int *data;
    int length;
    int capacity;
} vector;

static void push_back(vector *vector_instance, const int *data) {

    if(vector_instance->length >= vector_instance->capacity) {

        vector_instance->capacity *= 2;
        vector_instance->data = (int*) realloc(vector_instance->data, sizeof(int) * vector_instance->capacity);
    }
    vector_instance->data[vector_instance->length] = *data;
    vector_instance->length++;
}

static void vector_constructor(vector *vector_instance) {

    vector_instance->push_back = &push_back;
    vector_instance->length = 0;
    vector_instance->capacity = 2;
    vector_instance->data = (int*)malloc(sizeof(*vector_instance->data) * vector_instance->capacity);

}

static void vector_destructor(vector *vector_instance) {

    free(vector_instance->data);
    vector_instance->length = 0;
    vector_instance->capacity = 0;
    vector_instance->data = NULL;
}

主c
#include <stdio.h>
#include "vector.c"
#include <time.h>

static int isPrime (const int *number) {

    if((*number & 1) == 0) {
        if(*number == 2)
            return 1;
        else
            return 0;
    }

    for(int i = 3; (i * i) <= *number; i += 2) {

        if((*number % i) == 0)
            return 0;
    }

    return *number != 1;
}

int main(int argc, const char * argv[]) {
    vector v;
    vector_constructor(&v);
    clock_t start = clock();
    for(int i = 0; i <= 30000000; i++) {

        if(isPrime(&i))
            v.push_back(&v, &i);
    }
    clock_t end = clock();
    clock_t seconds = (end - start) / CLOCKS_PER_SEC;
    printf("%lu seconds \n", seconds);

    for(int i = 0; i < v.length; i++) {

        //printf("%d \n", v.data[i]);
    }
    vector_destructor(&v);
    return 0;
}

我用内置的Clang编译器在我的OS X小牛上编译这两个程序。
C++
g++ -O3 -std=c++11 Main.cpp

C类
gcc -O3 -std=c99 Main.c

两者都可以无故障编译,而且也可以无故障运行。
然而。。
我得到不同的时间结果。
C 12秒后完成
C++ 26秒后完成
有人能指出我做错了什么吗?
谢谢!

最佳答案

您的程序在isPrime中有细微的不同。在C++程序中:

for(int i = 3; (i * i) <= number; i++) {

在你的C程序中:
for(int i = 3; (i * i) <= *number; i += 2) {

所以,你的C++程序计算的余数是你的C程序的两倍,这很可能解释你的性能差异。
除此之外,我建议您不要通过引用或指针传递int,除非您有充分的理由。希望编译器足够聪明,能够找出不需要优化的地方,但是谁知道呢?
另外,如果可以的话,您希望避免通过函数指针调用函数,就像在C程序中那样。它们通常会损害编译器内联优化函数的能力。可能是编译器足够聪明,可以内联调用,但谁又知道呢?
最后,如果计算所有素数小于N,实际上是你所追求的,而这只是一个不适合C+C++的玩意儿,那么请看Sieve of EratosthenesSieve of Sundaram。或者,可以将已知素数的向量传递到isPrime中,只检查已知素数而不是所有奇数。

09-25 20:23