我做了一个简单的测试,我知道C ++更快但我的测试结果不切实际。
C ++代码是:
#include <stdio.h>
#include <windows.h>
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倍!没门!我的测试有什么问题?
答案 0 :(得分:6)
显示您使用的编译器选项。你的真实代码(#include <stdio>
不是真正的代码)。
您的C ++编译器比Java编译器更加智能(平均而言,这是正确的,但并非每个C ++编译器都比每个Java编译器更智能),并且它预先计算了结果。你唯一要计时的是printf
电话。
在Java使用的大多数任务中,它的表现与C ++一样。
VM语言(Java,C#)具有与JIT编译相关的额外成本,但也可以从更高效的内存分配和跨共享库的内联中获益。而C ++在访问OS系统调用方面要快得多。除此之外,可以仔细调整C ++内存布局以实现缓存行为;你没有在托管语言中获得这种控制水平。
这些因素中哪一个影响更大,完全取决于应用程序。任何做出“C ++比Java更快”或“Java总体上比C ++更快”的一揽子声明的人都是白痴。平均值无关紧要。您的申请表现很重要。
这是我的证明,gcc正在预先计算答案。
关于此代码:
#include <stdio.h>
#include <windows.h>
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
答案 1 :(得分:2)
我猜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 ++程序对于两个调用可能需要完全相同的时间,而在第二种情况下需要更长时间才能完成java。
答案 2 :(得分:-1)
首先,您可能不希望相应的打印功能成为您的基准测试的一部分,除非您真的关心它们的速度有多快。
关于Java或C ++是否更快,没有一个直接的答案......这取决于。当编译器可以进行一些不可用于C ++的优化时,Java可以更快。所以它取决于你具体做什么以及编译器选项是什么。