Spe*_*ood 4 c++ java visual-studio-2010 netbeans7.0
这是我之前提到的问题的后续问题:Java似乎比C++更快地执行简单算法.为什么?.通过这篇文章,我学到了一些重要的东西:
我试着写一个更简单的程序,它不使用指针(或Java等价的数组),并且在执行时非常简单.即便如此,Java执行速度也比C++执行速度快.我究竟做错了什么?
public class PerformanceTest2
{
public static void main(String args[])
{
//Number of iterations
double iterations = 1E8;
double temp;
//Create the variables for timing
double start;
double end;
double duration; //end - start
//Run performance test
System.out.println("Start");
start = System.nanoTime();
for(double i = 0;i < iterations;i += 1)
{
//Overhead and display
temp = Math.log10(i);
if(Math.round(temp) == temp)
{
System.out.println(temp);
}
}
end = System.nanoTime();
System.out.println("End");
//Output performance test results
duration = (end - start) / 1E9;
System.out.println("Duration: " + duration);
}
}
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
#include <cmath>
#include <windows.h>
using namespace std;
double round(double value)
{
return floor(0.5 + value);
}
void main()
{
//Number of iterations
double iterations = 1E8;
double temp;
//Create the variables for timing
LARGE_INTEGER start; //Starting time
LARGE_INTEGER end; //Ending time
LARGE_INTEGER freq; //Rate of time update
double duration; //end - start
QueryPerformanceFrequency(&freq); //Determinine the frequency of the performance counter (high precision system timer)
//Run performance test
cout << "Start" << endl;
QueryPerformanceCounter(&start);
for(double i = 0;i < iterations;i += 1)
{
//Overhead and display
temp = log10(i);
if(round(temp) == temp)
{
cout << temp << endl;
}
}
QueryPerformanceCounter(&end);
cout << "End" << endl;
//Output performance test results
duration = (double)(end.QuadPart - start.QuadPart) / (double)(freq.QuadPart);
cout << "Duration: " << duration << endl;
//Dramatic pause
system("pause");
}
Run Code Online (Sandbox Code Playgroud)
对于1E8迭代:
C++执行= 6.45秒
Java执行= 4.64秒
根据Visual Studios,我的C++命令行参数是:
/Zi /nologo /W3 /WX- /O2 /Ob2 /Oi /Ot /Oy /GL /D "_MBCS" /Gm- /EHsc /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Release\C++.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue
Run Code Online (Sandbox Code Playgroud)
我使用新的round函数更改了c ++代码,并更新了执行时间.
我找到了问题的答案,感谢Steve Townsend和Loduwijk.在将我的代码编译成汇编并对其进行评估后,我发现C++程序集创建的内存移动方式比Java程序集更多.这是因为我的JDK使用的是x64编译器,而我的Visual Studio Express C++无法使用x64架构,因此本质上速度较慢.所以,我安装了Windows SDK 7.1,并使用这些编译器编译我的代码(在发行版中,使用ctrl + F5).目前的时间比例是:
C++:~2.2 s Java:~4.6 s
现在我可以用C++编译所有代码,最后获得我的算法所需的速度.:)
Bli*_*ndy 21
这是一个安全的假设,任何时候你看到Java超越C++,特别是如此巨大的差距,你做错了什么.由于这是专门针对这种微观微观优化的第二个问题,我觉得我应该建议找一个不那么徒劳的爱好.
这回答了你的问题:你正在使用C++(实际上,你的操作系统)是错误的.至于隐含的问题(如何?),这很简单:endl刷新流,Java继续缓冲它.替换你的cout行:
cout << temp << "\n";
Run Code Online (Sandbox Code Playgroud)
你不太了解基准测试来比较这种东西(我的意思是比较单个数学函数).我建议买一本关于测试和基准测试的书.
你肯定不想为输出计时.删除每个循环中的输出语句并重新运行,以便更好地比较您实际感兴趣的内容.否则,您还要对输出函数和视频驱动程序进行基准测试.结果速度实际上取决于您运行的控制台窗口是否在测试时被遮挡或最小化.
确保您没有在C++中运行Debug构建.这将比Release更慢,与您启动流程的方式无关.
编辑:我在本地重现了这个测试场景,但无法得到相同的结果.修改代码(如下)以删除输出,Java需要5.40754388秒.
public static void main(String args[]) { // Number of iterations
double iterations = 1E8;
double temp; // Create the variables for timing
double start;
int matches = 0;
double end;
double duration;
// end - start //Run performance test
System.out.println("Start");
start = System.nanoTime();
for (double i = 0; i < iterations; i += 1) {
// Overhead and display
temp = Math.log10(i);
if (Math.round(temp) == temp) {
++matches;
}
}
end = System.nanoTime();
System.out.println("End");
// Output performance test results
duration = (end - start) / 1E9;
System.out.println("Duration: " + duration);
}
Run Code Online (Sandbox Code Playgroud)
下面的C++代码需要5062 ms.这是Windows上的JDK 6u21和VC++ 10 Express.
unsigned int count(1E8);
DWORD end;
DWORD start(::GetTickCount());
double next = 0.0;
int matches(0);
for (int i = 0; i < count; ++i)
{
double temp = log10(double(i));
if (temp == floor(temp + 0.5))
{
++count;
}
}
end = ::GetTickCount();
std::cout << end - start << "ms for " << 100000000 << " log10s" << std::endl;
Run Code Online (Sandbox Code Playgroud)
编辑2:如果我更准确地从Java恢复你的逻辑,那么对于C++和Java来说几乎完全相同,这是我所期望的,因为它依赖于log10实现.
5157ms,100000000 log10s
用于100000000 log10s的5187ms(双循环计数器)
1001200 log10s为5312ms(双循环计数器,圆为fn)
| 归档时间: |
|
| 查看次数: |
1580 次 |
| 最近记录: |