我有两个块做同样的事情。
if(print) for(int i = 0; i < numt; i++) if(primes[i]) {
printf("%d\n", i);
numprimes++;
}
//fast
else if(!print) for(int i = 0; i < numt; i++) if(primes[i]) {
numprimes++;
}
和
if(print) for(int i = 0; i < numt; i++) if(primes[i]) {
printf("%d\n", i);
numprimes++;
}
//very slow
else for(int i = 0; i < numt; i++) if(primes[i]) {
numprimes++;
}
我估计第一个比第二个快一倍。为什么是这样?效果发生在多个编译器中(Mingw,msvc)。默认情况下,print
为false,但您可以使用命令行args更改它。我在两种情况下都没有运行程序。这真是个谜......
整个文件:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
int main(int argc, char* argv[]) {
int numt = 1000000;
int sqrtt = sqrt(numt);
bool* primes = malloc(numt*sizeof(int));
int numprimes = 0;
bool print = true;
time_t start, end;
if(argc > 2) if(!strcmp(argv[2], "-np")) print = false;
if(argc > 1) sscanf(argv[1], "%d", &numt);
if(primes == NULL) {
printf("error in allocation");
return 1;
}
memset(primes, true, numt);
primes[0] = false;
primes[1] = false;
for(long long id = 1; id <= sqrtt; id++) if(primes[id]) for(long long cl = id*id; cl <= numt; cl+= id) primes[cl] = false;
start = clock();
//start block
if(print) for(int i = 0; i < numt; i++) if(primes[i]) {
printf("%d\n", i);
numprimes++;
}
else for(int i = 0; i < numt; i++) if(primes[i]) { //diff line
numprimes++;
}
//end block
end = clock();
free(primes);
printf("%d Primes before %d took %d", numprimes, numt, end-start);
return 0;
}
exe fast:https://drive.google.com/file/d/0B8ujl0shCPcHRTRENzFyeHpkd0U/edit?usp=sharing
exe慢:https://drive.google.com/file/d/0B8ujl0shCPcHcmZQNDlLLTZ3OWM/edit?usp=sharing
视频演示:http://youtu.be/45L4qkaPDmE
这是一个要比较的c ++版本:
#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <ctime>
#include <Windows.h>
#include <omp.h>
#include <thread>
using namespace std;
int main(int argc, char* argv[])
{
const double s = GetTickCount();
long long numt; //max number to compute to
if(argc < 2) {
cout << "Usage: "<<argv[0]<<" <primes until...>" << endl;
return 1;
}
else if(atoi(argv[1])<1) {
cout << "Usage: "<<argv[0]<<" <primes until...>" << endl;
return 1;
}
numt = atol(argv[1])+1;
bool skipprint = false;
if(argc >=3) if(!strcmp(argv[2], "noprint")) skipprint = true;
vector<bool> primes(numt);
primes.assign(numt, true);
primes[0] = false; //0 is not prime
primes[1] = false; //1 is also not prime but we do not want to eliminate all multiples of 1 (all numbers)
//#pragma omp parallel
{
const long long sqrtt = sqrt(numt); //don't need to go past sqrt(n) to eliminate all composites
//#pragma omp parallel for
for(long long id = 1; id <= sqrtt; id++) {
if(primes[id]) {
//#pragma omp for
for(long long cl = id*id; cl <= numt; cl+= id) primes[cl] = false;
}
}
//#pragma omp parallel for
//for(long long cl = l*l; cl <= numt; cl+= l) primes[cl] = false;
}
const double m = GetTickCount();
unsigned long long count = 0;
//this is the block
if(!skipprint) for(long long l = 2; l<numt; l++) if(primes[l]) {
cout << l << endl;
count ++;
}
if(skipprint) for(long long l = 2; l<numt; l++) if(primes[l]) count ++;
//this is the end of the block
const double e = GetTickCount();
cout << endl;
cout << count << " primes less than or equal to " << numt-1 << endl;
cout << "Calculation took " << m-s << " ms";
if(!skipprint) cout << " and printing took " << e-m << " ms";
else cout << " and counting took " << e-m << " ms";
cout <<"." << endl;
return 0;
}
答案 0 :(得分:10)
对发布的代码的善意编辑掩盖了真正的问题。
原始代码是:
if(print) for(int i = 0; i < numt; i++) if(primes[i]) {
printf("%d\n", i);
numprimes++;
}
//fast
else if(!print) for(int i = 0; i < numt; i++) if(primes[i]) {
numprimes++;
}
和
if(print) for(int i = 0; i < numt; i++) if(primes[i]) {
printf("%d\n", i);
numprimes++;
}
//very slow
else for(int i = 0; i < numt; i++) if(primes[i]) {
numprimes++;
}
请注意原始代码段中的最后一个else if(!print)
和else for()
如何绑定到之前的if(primes[i])
,而不是初始if(print)
测试。 编辑添加了原始代码中没有的大括号并更改了其行为。
如果没有花括号,则两个代码段会执行不同的操作,因此无法比较性能。 我认为nimsson不寻常的编码风格导致了这个问题。