UPDATE 2:
Changing the target from x86 to anycpu has lowered the average execution time to 84ms per run, down from 282ms. Maybe I should split this off into a second thread?
UPDATE:
Thanks to Femaref below who pointed out some testing problems, and indeed, after following his suggestions, the times are lower, indicating that VM setup time was significant in Java, but probably not in C#. In C#, it was the debug symbols that were significant.
I updated my code to run each loop 10,000 times, and only output the average ms at the end. The only significant change I made was to the C# version where I switched to the StopWatch class for greater resolution. I stuck with milliseconds because it's good enough.
Results:
The testing changes don't explain why Java is (still) so much faster than C#. C# performance was better, but this can be explained entirely by removing the debug symbols. If you read Mike Two and I's exchange on the comments attached to this OP, you'll see I got ~280ms average in five runs of the C# code just by switching from Debug to Release.
Numbers:
- A 10,000 count loop of the unmodified Java code gave me an average of 45ms (down from 55ms)
- A 10,000 count loop of the C# code using the StopWatch class gave me an average of 282ms (down from 320ms)
All of this leaves the difference unexplained. In fact, the differential got worse. Java went from being ~5.8x faster to ~6.2x faster.
(Original post below)
I have a few different solutions to Project Euler problem 5, but the execution time difference between the two languages/platforms in this particular implementation intrigues me. I didn't do any optimization with compiler flags, just plain javac
(via commandline) and csc
(via Visual Studio).
Here's the Java code. It finishes in 55ms.
public class Problem005b { public static void main(String[] args) { long begin = System.currentTimeMillis(); int i = 20; while (true) { if ( (i % 19 == 0) && (i % 18 == 0) && (i % 17 == 0) && (i % 16 == 0) && (i % 15 == 0) && (i % 14 == 0) && (i % 13 == 0) && (i % 12 == 0) && (i % 11 == 0) ) { break; } i += 20; } long end = System.currentTimeMillis(); System.out.println(i); System.out.println(end-begin + "ms"); } }Here is the identical C# code. It finishes in 320ms
using System; namespace ProjectEuler05 { class Problem005 { static void Main(String[] args) { DateTime begin = DateTime.Now; int i = 20; while (true) { if ( (i % 19 == 0) && (i % 18 == 0) && (i % 17 == 0) && (i % 16 == 0) && (i % 15 == 0) && (i % 14 == 0) && (i % 13 == 0) && (i % 12 == 0) && (i % 11 == 0) ) { break; } i += 20; } DateTime end = DateTime.Now; TimeSpan elapsed = end - begin; Console.WriteLine(i); Console.WriteLine(elapsed.TotalMilliseconds + "ms"); } } }
long
, the other is aDateTime
struct. – BoltClock♦ May 10 '11 at 15:14