【发布时间】:2015-05-18 15:23:21
【问题描述】:
在阅读我的帖子之前,请考虑到我是 C 和 C++ 的新手。 我主要是一名托管代码开发人员。
我有两段相同的代码(至少我是这么认为的)。 一个在 C 中,一个在 C++ 中。 该代码基本上检查数字是否为质数,如果是,则将其存储在容器中。
C++
Main.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;
}
Main.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 Mavericks 上编译这两个程序。
C++
g++ -O3 -std=c++11 Main.cpp
C
gcc -O3 -std=c99 Main.c
两者都可以毫无问题地编译,并且它们也可以毫无问题地运行。 不过..
我得到不同的时间结果。
C 在 12 秒后完成
C++ 在 26 秒后完成
谁能指出我做错了什么? 谢谢!
【问题讨论】:
-
您的代码不太一样 -
isPrime中的循环具有不同的增量。不知道这是否会有所作为。 -
有趣的是,您的 C 代码通过函数指针调用 push_back,它仍然比您的 C++ 快得多。但我认为不同的循环增量是性能差异的主要原因。您的 C++ 版本的模数可能是 C 版本的两倍。
-
另外,STL
vector可能有不同的扩容规则。如果它使用capacity *= 1.5,它将调用new更多次。 -
@DrewMcGowen 我认为这会有很大的不同。 C++ 版本检查的分区数量是原来的两倍,运行时间大约是原来的两倍。
-
@Daniel,尝试进行两个不同的测试。首先 - 在 C 和 C++ 中添加向量 N 个数字,其次 - 检查 IsPrime(...) M 次。这将帮助您了解问题出在哪里,在函数中还是在向量中。我猜想在 C 中增加 +2 与在 C++ 中增加 +1 可能会使 C++ 中的操作增加两倍,所以这可能是您的结果的原因。
标签: c++ c performance benchmarking