Robert C. Martin的中文博库贴了一篇文章: 三大编程语言的性能PK--Java, C/C++和Ruby。里面说Java比C++快一些,引来粉丝们攻击。印象中Java应该只在某些特定的情况下比C/C++快,所以对他的结果我也表示怀疑。下面我试图找出真相。

为了方便测试,我把代码调整了一下:第一不把数组初始化的时间计入(测试数据表明,这样对C++没有好处。)第二,循环中每次都去调用sqrt(max),其实是个循环常量,提取出来(测试数据表明影响不大),否则就变成编译器的优化能力比较了。第三,统计全部时间,而不是在循环中每次计时。

调整后的Java和C++代码分别如下。在我的机器上,Java版使用的时间为3.5秒,而C++版的为4.0秒。如果不做第一点改动,则时间分别是4.3秒和4.8秒;注意Java的Arrays.fill是以for循环实现的。如果把C++版本的赋值改为memset,时间也就是4.3秒。改成VC版本之后,C++的测试数据基本上没有什么变化。这里把代码也列上了。

不过以上C++版本全部是未优化过的 (Java前面确省已经使用了)。下面的代码在打开全部优化之后的时间分别是:
Cygwin 3.3 (使用g++ -O3选项)
VC 3.4 (使用release版本)

可见在这里C++还是比Java快一点点的。C++粉丝们可以睡个安稳觉了。

JAVA:

c 与java性能 java和c的运行速度_java

public class GeneratePrimes {
    public static double generate(int max) ...{
      //long start = System.currentTimeMillis();
      boolean sieve[] = new boolean[max];
      Arrays.fill(sieve, true);
      sieve[0] = false;
      sieve[1] = false;
      int maxsqrt = (int)Math.sqrt(max);
      long start = System.currentTimeMillis();
      for (int i = 2; i < maxsqrt; i++) ...{
        if (sieve[i]) ...{
          for (int j = 2*i; j < max; j+=i) ...{
            sieve[j]= false;
          }
        }
      }

      return (System.currentTimeMillis() - start)/1000.0;
    } 
    
    public static void main(String args[]) ...{
        double time = 0.d;
        for (int i=100000; i<=5000000; i+=100000) ...{
            time += generate(i);
        }

        System.out.println(time);
    }
}

 
  
... 

Cygwin/C++:
 
#include <iostream>
#include <math.h>
#include <sys/time.h>

using namespace std;

double generate(int max) {
  struct timeval start;
  struct timezone tz;
  //gettimeofday(&start, &tz);

  bool *sieve = new bool[max];
  for (int i=0; i<max; i++) sieve[i] = true;
  //memset(sieve, 1, sizeof(bool) * max);
  sieve[0] = false;
  sieve[1] = false;
  int maxsqrt = (int)sqrt(max);
  gettimeofday(&start, &tz);
  for (int n=2; n<maxsqrt; n++) ...{
    if (sieve[n]) ...{
      for (int j=2*n; j<max; j+=n)
        sieve[j] = false;
    }
  }

  struct timeval end;
  gettimeofday(&end, &tz);
  
  double startSecond = start.tv_usec/1000000.0;
  double endSecond = (end.tv_sec - start.tv_sec) + end.tv_usec/1000000.0;
  return endSecond - startSecond;
}


int main(int ac, char** av) {
  double time = 0.0;
  for (int i=100000; i<=5000000; i+=100000) ...{
    time += generate(i);
  }
  cout << time << endl;
} 
   ... 
  ... 

VC/C++:
 
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <Windows.h>

using namespace std;

double generate(int max) {
  unsigned int start, end;

  bool *sieve = new bool[max];
  //for (int i=0; i<max; i++) sieve[i] = true;
  memset(sieve, 1, max*(sizeof(bool)));
  sieve[0] = false;
  sieve[1] = false;
  double maxsqrt = sqrt((double)max);
  start = GetTickCount();
  for (int n=2; n<maxsqrt; n++) ...{
    if (sieve[n]) ...{
      for (int j=2*n; j<max; j+=n)
        sieve[j] = false;
    }
  }

  end = GetTickCount();
  
  return (end - start)/1000.0;
}


int main(int ac, char** av) {
  double time = 0.0;
  for (int i=100000; i<=5000000; i+=100000) ...{
    time += generate(i);
  }
  cout << time << endl;
}    ...   ...