基准 C++与 Java,不切实际的结果
我做了一个简单的测试,我知道 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 毫秒
C++:0.013517 毫秒
它说 C++ 比 Java 快 206777 倍!决不!我的测试出了什么问题?
I did a simple test, I know C++ is faster but the results of my test is unrealistic.
C++ code is:
#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 code is:
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++ compiler: gcc 4.4.0 and Java: jdk 1.6.0
Java: 2795 ms
C++ : 0.013517 ms
It says C++ is 206777 times faster than Java! No way! What is wrong in my test?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
显示您使用的编译器选项。而您的真实代码(
#include
不是您的真实代码)。您的 C++ 编译器比 Java 编译器聪明得多(平均而言,在您的情况下确实如此,但并非每个 C++ 编译器都比每个 Java 编译器更聪明),并且它预先计算了结果。您唯一需要计时的是
printf
调用。在大多数使用 Java 的任务中,它的性能与 C++ 差不多。
VM 语言(Java、C#)具有与 JIT 编译相关的额外成本,但也受益于更高效的内存分配和跨共享库的内联。 C++ 访问操作系统系统调用的速度要快得多。除此之外,C++ 内存布局可以针对缓存行为进行仔细调整;在托管语言中您无法获得这种级别的控制。
这些因素中哪一个影响更大完全取决于应用程序。任何笼统地声明“C++ 总体上比 Java 更快”或“Java 总体上比 C++ 更快”的人都是白痴。平均数并不重要。您的应用程序的性能很重要。
这是我的证明,gcc 正在预先计算答案。
在此代码上:
使用 gcc-4.3.4,使用命令行
./g++-4 -omasoud-gcc.exe -O3 masoud.cpp
:相比之下,MSVC++ 16.00.40219.01 for x64 ( 2010 SP1),命令行
cl /Ox masoud.cpp
:VC++ 不会预先计算答案,但 64 位代码的循环执行速度确实快了三倍多。这是Java应该接近的速度。
更有趣的事实:gcc 预先计算答案的速度比它生成的代码计算速度更快。 gcc 的编译时间:
Show the compiler options you used. And your REAL code (
#include <stdio>
isn't your real code).Your C++ compiler is much smarter than your Java compiler (this is true on average and in your case, but not every C++ compiler is smarter than every Java compiler), and it precomputed the result. The only thing you're timing is the
printf
call.On most of the tasks Java is used for, it performs about as well as C++.
VM languages (Java, C#) have additional costs related to JIT compilation, but also benefit from more efficient memory allocation and inlining across shared libraries. And C++ is much much faster at accessing OS syscalls. Beyond that, C++ memory layouts can be carefully tuned for cache behavior; you don't get that level of control in managed languages.
Which of these factors has more influence is completely application-specific. Anyone making a blanket statement that "C++ is faster in general than Java" or "Java is faster in general than C++" is an idiot. Averages don't matter. Performance on YOUR application matters.
And here is my proof, that gcc is precomputing the answer.
On this code:
With gcc-4.3.4, using the command-line
./g++-4 -omasoud-gcc.exe -O3 masoud.cpp
:By comparison, MSVC++ 16.00.40219.01 for x64 (2010 SP1), command-line
cl /Ox masoud.cpp
:VC++ isn't precomputing the answer, but 64-bit code does execute the loop more than three times faster. This is the speed that Java ought to approach.
More fun facts: gcc precomputes the answer faster than the code it generates to calculate it out. Compile time for gcc:
我猜 gcc 将您的
s
方法编译为:...而 java JIT 没有。
我不是专家,但 gcc 优化过程可能包含比 JIT 在合理时间内可以完成的更多的传递。这也是为什么 gcc 编译可能需要很长时间,而 java 程序会立即启动(尽管 JIT 必须在程序运行之前编译、链接和优化所有内容)。
java 编译器 (javac) 执行的优化非常少,例如常量折叠,但仅此而已。每个主要的优化(内联等)都是由 JIT 完成的,所以如果它不想让用户在启动之前等待太久,就必须抓紧时间。另一方面,由于 gcc 静态编译和优化所有内容,因此需要的时间就可以。
编辑:
知道优化是否存在差异应该很简单:使用 s(1000) 运行两个程序,然后使用 s(100000000000000) 运行。如果我是真的,c++ 程序可能需要完全相同的时间来完成这两个调用,而 java 程序在第二种情况下需要更长的时间才能完成。
I guess that gcc compiled your
s
method into:...while the java JIT did not.
I'm no expert but gcc optimization process may contain more passes than what the JIT can do in a reasonable time. That's also why a gcc compilation may take ages while a java program launches itself immediatly (altough the JIT has to compile, link and optimize everything before the program can be run).
The java compiler (javac) does very few optimization, like constant folding, but that's pretty much all. Every major optimization (inlining, etc) is done by the JIT, so if it does not want the user to wait too long before launch, it must hurry. On the other hand, since gcc compiles and optimize everything statically, it can take as long as it needs.
EDIT:
It should be simple to know if there is a difference in optimizations: run your two programs with s(1000) and then with s(100000000000000). If I'm true, the c++ program may take the exact same time for both calls, while the java one while take longer to complete in the second case.
首先,您可能不希望相应的打印功能成为基准测试的一部分,除非您真的关心它们的速度。
关于 Java 或 C++ 哪个更快,没有直接的答案……这取决于情况。当编译器可以进行一些 C++ 无法实现的优化时,Java 会更快。因此,这取决于您具体在做什么以及编译器选项是什么。
First of all, you probably don't want the respective print functions to be part of your benchmark unless you really care how fast those are.
There's not a straight answer as to whether Java or C++ is faster...it depends. Java can be faster when the compiler can do some optimizations that would not be available for C++. So it depends on what specifically you are doing and what the compiler options are.