Open Side Menu Go to the Top

04-21-2013 , 08:37 PM
Testing how fast C# and Java are able to compute sqrt, log, exp etc on a billion iterations. Something seems wrong, because C# is lagging by a lot. Anything I'm doing wrong? Fwiw, I'm running the C# .exe from bin/release.

Java (~320ms):
Code:
import java.text.DecimalFormat;

public class TimingTest {
	public static void main(String[] args){
		final long maxIterations = 1000000000;
		DecimalFormat formatter = new DecimalFormat("0.###E0");
		String f = formatter.format(maxIterations);
		System.out.println("Beginning test on " + f + " iterations...");
		final long start = System.currentTimeMillis();
		for (long i = 1; i < maxIterations; i++) Math.sqrt(i);
		final long stop = System.currentTimeMillis();
		final long elapsed = (stop - start); 
		System.out.println("Time elapsed: " + elapsed);
	}
}
C# (~950ms):
Code:
namespace TimingTest
{
    class Program
    {
        static void Main(string[] args)
        {
            long maxIterations = 1000000000;
            Console.WriteLine("Beginning test on " + maxIterations.ToString("0.###E0") + " iterations...");
            DateTime start = DateTime.Now;
            for (long i = 1; i < maxIterations; i++) Math.Sqrt(i);
            double elapsed = DateTime.Now.Subtract(start).TotalMilliseconds;
            Console.WriteLine("Time elapsed: " + elapsed);
            Console.Read();
        }
    }
}
Python (too slow...):
Code:
from math import sqrt
maxIterations = 1000000000
i = 1

while i < maxIterations:
    sqrt(i)
    i = i + 1
TimingTest: C# vs Java Quote
TimingTest: C# vs Java
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards ? Splash Pots ? CoinRaces
TimingTest: C# vs Java
04-21-2013 , 11:45 PM
Code:
from math import sqrt
maxIterations = 1000000000
i = 1

while i < maxIterations:
    sqrt(i)
    i = i + 1
Complete tangent but "for i in xrange(maxIterations):" should be 30% faster or so than this while loop
TimingTest: C# vs Java Quote
04-22-2013 , 01:01 AM
It seems unlikely that your CPU can do a billion square roots in 350ms. So the compiler is probably optimizing it out. Maybe try something like this:
Code:
...
double total = 0.0;
for (long i = 0; i < maxIterations; i++)
    total += Math.sqrt(i);
System.out.println("Total: " + total);
...
TimingTest: C# vs Java Quote
04-22-2013 , 01:18 AM
Also what optimization level are you using?

To avoid the compiler doing it for you you could populate an array with random numbers first and then take the square root of each.
TimingTest: C# vs Java Quote
04-22-2013 , 01:29 AM
Quote:
Originally Posted by spiral
Complete tangent but "for i in xrange(maxIterations):" should be 30% faster or so than this while loop
Thanks, I used range() initially and got a memory problem. Clearly still learning Python. But in any case (xrange or for), the program is so slow it didn't terminate even after 2 minutes and not accumulating the sum like below.

Quote:
Originally Posted by sards
It seems unlikely that your CPU can do a billion square roots in 350ms. So the compiler is probably optimizing it out. Maybe try something like this:
Java: ~8400ms
C#: ~17000ms
TimingTest: C# vs Java Quote
04-22-2013 , 02:34 AM
Quote:
Originally Posted by jmark
Also what optimization level are you using?
I don't know what you mean.

Quote:
Originally Posted by jmark
To avoid the compiler doing it for you you could populate an array with random numbers first and then take the square root of each.
This was it. I don't know much about compilers. Can anyone explain what's going on here? And in general, can I expect much performance difference between Java and C#?

On 100 million random square roots on numbers between 1 and 100:
Java: 452
C#: 442

Java
Code:
import java.text.DecimalFormat;

public class TimingTest {
	public static void main(String[] args){
		final int maxIterations = 100000000;
		double total = 0.0;
		
		long[] rnd = new long[maxIterations];
		for (int i = 0; i < maxIterations; i++) 
			rnd[i] = Math.round(Math.random()*100);
		
		DecimalFormat formatter = new DecimalFormat("0.###E0");
		String f = formatter.format(maxIterations);
		System.out.println("Beginning test on " + f + " iterations...");
		
		final long start = System.currentTimeMillis();
		for (int i = 0; i < maxIterations; i++) total += Math.sqrt(rnd[i]);
		final long stop = System.currentTimeMillis();
		
		final long elapsed = (stop - start); 
		System.out.println("Time elapsed: " + elapsed);
		System.out.println("Sum: " + total);
	}
}

C#
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TimingTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int maxIterations = 100000000;
            double total = 0.0;

            int[] rnd = new int[maxIterations];
            Random rng = new Random();
            for (int i = 0; i < maxIterations; i++) 
                rnd[i] = rng.Next(100);

            Console.WriteLine("Beginning test on " + maxIterations.ToString("0.###E0") + " iterations...");

            DateTime start = DateTime.Now;
            for (long i = 0; i < maxIterations; i++) total += Math.Sqrt(rnd[i]);
            double elapsed = DateTime.Now.Subtract(start).TotalMilliseconds;

            Console.WriteLine("Time elapsed: " + elapsed);
            Console.WriteLine("Sum: " + total);
            Console.Read();
        }
    }
}
TimingTest: C# vs Java Quote
04-22-2013 , 08:53 AM
Quote:
Originally Posted by :::grimReaper:::
I don't know what you mean.



This was it. I don't know much about compilers. Can anyone explain what's going on here? And in general, can I expect much performance difference between Java and C#?

On 100 million random square roots on numbers between 1 and 100:
Java: 452
C#: 442

Java
Code:
import java.text.DecimalFormat;

public class TimingTest {
	public static void main(String[] args){
		final int maxIterations = 100000000;
		double total = 0.0;
		
		long[] rnd = new long[maxIterations];
		for (int i = 0; i < maxIterations; i++) 
			rnd[i] = Math.round(Math.random()*100);
		
		DecimalFormat formatter = new DecimalFormat("0.###E0");
		String f = formatter.format(maxIterations);
		System.out.println("Beginning test on " + f + " iterations...");
		
		final long start = System.currentTimeMillis();
		for (int i = 0; i < maxIterations; i++) total += Math.sqrt(rnd[i]);
		final long stop = System.currentTimeMillis();
		
		final long elapsed = (stop - start); 
		System.out.println("Time elapsed: " + elapsed);
		System.out.println("Sum: " + total);
	}
}

C#
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TimingTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int maxIterations = 100000000;
            double total = 0.0;

            int[] rnd = new int[maxIterations];
            Random rng = new Random();
            for (int i = 0; i < maxIterations; i++) 
                rnd[i] = rng.Next(100);

            Console.WriteLine("Beginning test on " + maxIterations.ToString("0.###E0") + " iterations...");

            DateTime start = DateTime.Now;
            for (long i = 0; i < maxIterations; i++) total += Math.Sqrt(rnd[i]);
            double elapsed = DateTime.Now.Subtract(start).TotalMilliseconds;

            Console.WriteLine("Time elapsed: " + elapsed);
            Console.WriteLine("Sum: " + total);
            Console.Read();
        }
    }
}
Are you doing a lot of "number crunching" with your programs? If not your test doesn't reveal much about relative overhead in execution. All you're doing is essentially a few floating point calcs that have really pretty much nothing to do with how the vast majority of programs operate

Again, problem domain should dictate your language choice.
TimingTest: C# vs Java Quote
04-22-2013 , 01:14 PM
That is true. But in general the performance of C# and Java will be comparable, to the point that performance should not be the deciding factor in choosing between them. If you absolutely need the best possible performance, use C++ instead.
TimingTest: C# vs Java Quote
04-22-2013 , 03:09 PM
Quote:
Originally Posted by :::grimReaper:::
This was it. I don't know much about compilers. Can anyone explain what's going on here?
You're not using the result of the square root and consequently your loop is not doing anything so the compiler completely omits it.

Be careful you're not measuring the speed of the square root function itself (unless you need to of course) as they may not be the same.
TimingTest: C# vs Java Quote
04-22-2013 , 05:34 PM
Quote:
Originally Posted by sards
That is true. But in general the performance of C# and Java will be comparable, to the point that performance should not be the deciding factor in choosing between them. If you absolutely need the best possible performance, use C++ instead.
But looking at the initial runs, seems like the Java compiler is more "smart," or may optimize execution as seen in the initial runs.
TimingTest: C# vs Java Quote
04-22-2013 , 05:37 PM
Quote:
Originally Posted by skier_5
You're not using the result of the square root and consequently your loop is not doing anything so the compiler completely omits it.

Be careful you're not measuring the speed of the square root function itself (unless you need to of course) as they may not be the same.
Interesting. In my second test, I stored the cumulative sum of the square roots, and Java was still outperforming. It wasn't until I was taking square roots of random integers that they were equal in performance. Why?
TimingTest: C# vs Java Quote
04-22-2013 , 07:41 PM
In C you can set the optimization flags, like -O2 and -O3 etc. I'm sure there's something similar in Java. If you want the fastest code execution for the loop:

for i = 1 to 10
total += i;

the compiler can just replace that whole for loop with:
total = 55;
TimingTest: C# vs Java Quote
04-22-2013 , 08:44 PM
A lot of the time in that test is spent on unnecessary type conversion. Try changing this line:
Code:
for (long i = 0; i < maxIterations; i++)
to this:
Code:
for (double i = 0; i < maxIterations; i++)
TimingTest: C# vs Java Quote
04-22-2013 , 09:38 PM
Quote:
Originally Posted by sards
A lot of the time in that test is spent on unnecessary type conversion. Try changing this line:
Code:
for (long i = 0; i < maxIterations; i++)
to this:
Code:
for (double i = 0; i < maxIterations; i++)
No don't do that. Using doubles for the loop control is not a good idea. Just use another double var. Don't use rnd () to load the array as part of the loop, load the array and then run the test. The test is bogus though, it doesn't matter much.
TimingTest: C# vs Java Quote
04-22-2013 , 10:55 PM
Quote:
Originally Posted by :::grimReaper:::
Interesting. In my second test, I stored the cumulative sum of the square roots, and Java was still outperforming. It wasn't until I was taking square roots of random integers that they were equal in performance. Why?
maybe cause the java compiler just can't optimize fair enough with random numbers
TimingTest: C# vs Java Quote
04-23-2013 , 02:54 AM
Quote:
Originally Posted by adios
load the array and then run the test.
That's what I did
TimingTest: C# vs Java Quote
04-23-2013 , 03:58 AM
Quote:
Originally Posted by adios
No don't do that. Using doubles for the loop control is not a good idea.
I would agree if the point of this exercise were to write good code. But in fact the point is to experiment and see how various code constructs affect compiler optimizations.
TimingTest: C# vs Java Quote
04-23-2013 , 09:47 AM
Quote:
Originally Posted by sards
I would agree if the point of this exercise were to write good code. But in fact the point is to experiment and see how various code constructs affect compiler optimizations.
Which brings up what is the point of this? If it is a comparison of how Java and C# handle sqrt ok. Is or a comparison of different compilers? It fails then. If it is a comparison of overhead imposed? Another fail.
TimingTest: C# vs Java Quote
04-23-2013 , 09:53 AM
Quote:
Originally Posted by :::grimReaper:::
That's what I did
How much is rnd () introducing into the overall timng?

When I look at what you're doing I am a little concerned that you are drawing erroneous conclusions from the results. Hopefully you are experimenting and not making hard and fast conclusions about the languages.
TimingTest: C# vs Java Quote
04-23-2013 , 03:33 PM
Quote:
Originally Posted by adios
How much is rnd () introducing into the overall timng?
0. As you can see the in code (post 6), random numbers are created and stored in an array first.
TimingTest: C# vs Java Quote
04-23-2013 , 08:35 PM
Quote:
Originally Posted by sards
A lot of the time in that test is spent on unnecessary type conversion. Try changing this line:
Code:
for (long i = 0; i < maxIterations; i++)
to this:
Code:
for (double i = 0; i < maxIterations; i++)
Actually it really isn't, changing the ints to doubles in the code in post 6 only made a ~10ms difference on my machine, which is a bit slower than OP's. Total elapsed time of about 630ms versus 640 with the 100 million casts from int to double.
TimingTest: C# vs Java Quote
04-23-2013 , 09:12 PM
Quote:
Originally Posted by adios
Which brings up what is the point of this?
Yeah, I was curious about that too. As a learning exercise its cool but if OP was hoping for useful information about the relative performance of Java vs C# it probably fails.
TimingTest: C# vs Java Quote
04-25-2013 , 06:21 PM
Don't know about sqrt but one reason C# will be always slower than Java at number crunching is that it (current implementations) doesn't utilize some of the instructions of modern processors.
You can try googling SIMD and C# for more if you are interested in your specific case but my suspicion is that it's the reason.
TimingTest: C# vs Java Quote
04-25-2013 , 06:45 PM
Quote:
Originally Posted by punter11235
Don't know about sqrt but one reason C# will be always slower than Java at number crunching is that it (current implementations) doesn't utilize some of the instructions of modern processors.
You can try googling SIMD and C# for more if you are interested in your specific case but my suspicion is that it's the reason.
I would think that if C# didn't take advantage of floating point instructions while Java did the relative time difference would be even greater.
TimingTest: C# vs Java Quote
04-25-2013 , 07:11 PM
I am clueless when it comes to details as I don't really do C# but I remember even very simple number crunching loops written in C gained a lot after enabling SSE2/4 comparing to C# equivalent. I remember doing some research (googling) back then and gaining the impression that the situation is better in Java.
You might be right the the difference should be bigger in case of sqrt. I don't know, just wanted to point possible reason for that whch I encountered in my experience.

This btw sounds like great material for StackOverflow question. Some smart people there or sure know the answer and will give it to you for mere upvote

Last edited by punter11235; 04-25-2013 at 07:17 PM.
TimingTest: C# vs Java Quote
TimingTest: C# vs Java
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards ? Splash Pots ? CoinRaces
TimingTest: C# vs Java

      
m