基准C ++与Java,不切实际的结果

我做了一个简单的测试,我知道C ++更快但我的测试结果不切实际。

C ++代码是:

#include  #include  unsigned long long s(unsigned long long n) { unsigned long long s = 0; for (unsigned long long i = 0; i < n; i++) s += i; return s; } int main() { LARGE_INTEGER freq, start, end; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&start); printf("%llu\n", s(1000000000)); QueryPerformanceCounter(&end); double d = (double) (end.QuadPart - start.QuadPart) / freq.QuadPart * 1000.0; printf("Delta: %f\n", d); return 0; } 

Java代码是:

 public class JavaApplication5 { public static long s(long n) { long s = 0; for (long i = 0; i < n; i++) { s += i; } return s; } public static void main(String[] args) { long start = System.nanoTime(); System.out.println(s(1000000000)); long end = System.nanoTime(); System.out.println((end - start)/1000000); } } 

C ++编译器:gcc 4.4.0和Java:jdk 1.6.0

Java: 2795 ms

C++ : 0.013517 ms

它说C ++比Java快206777倍! 没门! 我的测试有什么问题?

显示您使用的编译器选项。 而你的真实代码( #include 不是你真正的代码)。

您的C ++编译器比Java编译器更加智能(在您的情况下这是正确的,但并非每个C ++编译器都比每个Java编译器更智能),并且它预先计算了结果。 你唯一要计时的是printf调用。

在Java使用的大多数任务中,它的表现与C ++一样。

VM语言(Java,C#)具有与JIT编译相关的额外成本,但也受益于更高效的内存分配和跨共享库的内联。 而C ++在访问OS系统调用方面要快得多。 除此之外,可以仔细调整C ++内存布局以实现缓存行为; 你没有在托管语言中获得这种级别的控制。

哪些因素影响更大是完全针对特定应用的。 任何人都在做一句“C ++比Java更快”或“Java比C ++更快”的一揽子声明,这是一个白痴。 平均值无关紧要。 您的申请表现很重要。


这是我的certificate,gcc正在预先计算答案。

在这段代码上:

 #include  #include  unsigned long long s(unsigned long long n) { unsigned long long s = 0; for (unsigned long long i = 0; i < n; i++) s += i; return s; } int main( int argc, char** argv ) { LARGE_INTEGER freq, start, end; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&start); printf("%llu\n", s(1000000000)); QueryPerformanceCounter(&end); double d = (double) (end.QuadPart - start.QuadPart) / freq.QuadPart * 1000.0; printf("Delta: %f\n", d); QueryPerformanceCounter(&start); printf("%llu\n", s(atol(argv[1]))); QueryPerformanceCounter(&end); d = (double) (end.QuadPart - start.QuadPart) / freq.QuadPart * 1000.0; printf("Delta: %f\n", d); return 0; } 

使用gcc-4.3.4,使用命令行./g++-4 -omasoud-gcc.exe -O3 masoud.cpp

 bash-3.2# ./masoud-gcc 1000000000 499999999500000000 Delta: 0.845755 499999999500000000 Delta: 1114.105866 

相比之下,MSVC ++ 16.00.40219.01 for x64(2010 SP1),命令行cl /Ox masoud.cpp

 > masoud 1000000000 499999999500000000 Delta: 229.684364 499999999500000000 Delta: 354.275606 

VC ++没有预先计算答案,但64位代码确实执行循环的速度提高了三倍以上。 这是Java应该接近的速度。


更有趣的事实:gcc比它生成的代码更快地预先计算答案以计算出答案。 编译gcc的时间:

 real 0m0.886s user 0m0.248s sys 0m0.185s 

我想gcc将你s方法编译成:

 unsigned long long s(unsigned long long n) { return n*(n+1)/2; } 

…虽然java JIT没有。

我不是专家,但gcc优化过程可能包含比JIT在合理时间内可以做的更多的传递。 这也是为什么gcc编译可能需要很长时间才能使java程序立即启动(尽管JIT必须在程序运行之前编译,链接和优化所有内容)。

java编译器(javac)很少进行优化,比如常量折叠,但这几乎都是。 每个主要的优化(内联等)都是由JIT完成的,所以如果它不希望用户在启动之前等待太久,它必须快点。 另一方面,由于gcc静态编译和优化所有内容,因此只需要它就可以使用。

编辑:

应该很容易知道优化是否存在差异:使用s(1000)然后使用s(100000000000000)运行两个程序。 如果我是真的,那么c ++程序对于两个调用可能需要完全相同的时间,而在第二种情况下需要更长时间才能完成。

首先,您可能不希望各自的打印function成为您的基准测试的一部分,除非您真正关心它们的速度有多快。

关于Java或C ++是否更快,没有一个直接的答案……这取决于。 当编译器可以进行一些不可用于C ++的优化时,Java可以更快。 所以这取决于你具体做什么以及编译器选项是什么。