Introduction
This is a follow up question to the one I asked previously: Java seems to be executing bare-bones algorithms faster than C++. Why?. Through that post, I learned a few important things:
- I was not using Ctrl + F5 to compile and run c++ code on Visual Studios C++ Express, and this was resulting in debuging that slowed down the code execution.
- Vectors are as good (if not better) than pointers at handling arrays of data.
- My C++ is terrible. ^_^
- A better test of execution time would be iteration, rather than recursion.
I tried to write a simpler program, which does not use pointers (or arrays in the Java equivalent), and which is pretty straightforward in its execution. Even then, the Java execution is faster than the C++ execution. What am I doing wrong?
Code:
Java:
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);
}
}
C++:
#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");
}
Observations:
For 1E8 iterations:
C++ Execution = 6.45 s
Java Execution = 4.64 s
Update:
According to Visual Studios, my C++ commandline arguments are:
/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
Update 2:
I changed the c++ code with the new round function, and I updated the time of execution.
Update 3:
I found the answer to the problem, with thanks to Steve Townsend and Loduwijk. Upon compiling my code into assembly and evaluating it, I found that the C++ assembly was creating way more memory movements than the Java assembly. This is because my JDK was using an x64 compiler, while my Visual Studio Express C++ could not use the x64 architecture, and was thus inherently slower. So, I installed the Windows SDK 7.1, and used those compilers to compile my code (in release, using ctrl + F5). Presently the time ratios are:
C++: ~2.2 s Java: ~4.6 s
Now I can compile all my code in C++, and finally get the speed that I require for my algorithms. :)