I wrote some code to test performance for arrays in both C#(.NET CLR) and Java(Java 8, Windows). For normal flat arrays, .NET showed to be a little faster than Java.
When I wrote some code for testing 2d arrays (using jagged arrays), I noticed a clear gap between Java and C#. Java version running more than 2x faster than C#!
Here's my C# code:
class ArrayTest
{
public int [][] jagged;
public ArrayTest(int width, int height)
{
Height = height;
Width = width;
Random rng = new Random();
jagged = new int[height][];
for (int i = 0; i < height; i++)
{
jagged[i] = new int[width];
for (int j = 0; j < width; j++)
{
jagged[i][j] = rng.Next(1024);
}
}
}
public int Height { get; private set; }
public int Width { get; private set; }
public void DoMath(ArrayTest a)
{
for (int i = 0; i < Height; i++)
{
for (int j = 0; j < Width; j++)
{
jagged[i][j] *= a.jagged[i][j];
}
}
}
}
class Program
{
static void Main(string[] args)
{
const int loop = 500;
int width = 800, height = 800;
ArrayTest a1 = new ArrayTest(width, height),
a2 = new ArrayTest(width, height);
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < loop; i++)
{
a1.DoMath(a2);
}
sw.Stop();
Console.WriteLine("Time taken: " + sw.ElapsedMilliseconds);
Console.ReadKey();
}
}
In my computer, the measured part takes about 2200ms to run.
Here's the Java version:
public class ArrayTest {
private int width, height;
private int[][] array;
public ArrayTest(int width, int height) {
this.width = width;
this.height = height;
array = new int[height][width];
Random rng = new Random();
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
array[i][j] = rng.nextInt(1024);
}
}
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int[][] getArray() {
return array;
}
public void doMath(ArrayTest a) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
array[i][j] *= a.array[i][j];
}
}
}
}
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
final int loop = 500;
int width = 800,
height = 800;
ArrayTest a1 = new ArrayTest(width, height),
a2 = new ArrayTest(width, height);
long start, end;
start = java.lang.System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
a1.doMath(a2);
}
end = java.lang.System.currentTimeMillis();
System.out.println("Elapsed time: " + (end - start));
}
}
It takes about 930ms to run.
Until now, it is C# 2200ms vs Java 930ms.
However, when I change my C# method to look like this:
public void DoMath(ArrayTest a)
{
int[][] _jagged = this.jagged,
_a = a.jagged;
int[] __jagged, __a;
for (int i = 0; i < _jagged.Length; i++)
{
__jagged = _jagged[i];
__a = _a[i];
for (int j = 0; j < __jagged.Length; j++)
{
__jagged[j] *= __a[j];
}
}
}
Then my C# code becomes as fast as Java! (930ms) I took a really long time until I got to this code, and I'm still not sure why it is fastest than the first version (and way uglier).
So, here are my questions:
- Why is this last code so much more eficiente than the first one?
- Can I rewrite it so that it becomes even more efficient (or less ugly, but as efficient as this one)?
[edit]
I'm using .NET 4.5 and Java 8, both are console applications. The .NET version I'm running in release mode and without the VS debugger attached.
[edit 2]
Just to be clear: it is NOT a micro-benchmark or anything like that. I just want to make operations through 2d arrays faster than (or as fast as) Java, and I prefer to have a cleaner code.