Java与.NET性能

时间:2015-04-29 03:47:19

标签: java c# performance jvm clr

在我编写这个小代码以比较我的计算机中的.NET 4.5和Java 8性能后,我感到非常惊讶:

class ArrayTest
{
    public int[][] jagged;

    public ArrayTest(int width, int height)
    {
        Height = height;
        Width = width;
        Random rng = new Random();
        jagged = new int[width][];
        for (int i = 0; i < height; i++)
        {
            jagged[i] = new int[width];
            for (int j = 0; j < jagged[i][j]; j++)
            {
                jagged[i][j] = rng.Next(2048);
            }
        }
    }
    public int this[int i, int j]
    {
        get
        {
            return jagged[i][j];
        }
        set
        {
            jagged[i][j] = value;
        }
    }

    public void DoMath(ArrayTest a)
    {
        for (int i = 0; i < Height; i++)
        {
            for (int j = 0; j < Width; j++)
            {
                this[i, j] *= a[i, j];
            }
        }
    }

    public int Height { get; private set; }

    public int Width { get; private set; }
}



class Program
{
    static void Main(string[] args)
    {
        Random rng = new Random();
        const int loop = 10;
        int width = 10000,
            height = 10000;

        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();
    }
}

以下是Java版本:

    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(2048);
            }
        }
    }

    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.getArray()[i][j];
            }
        }
    }

}

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        final int loops = 10;
        int width = 10000, height = 10000;
        ArrayTest a1 = new ArrayTest(width, height),
                a2 = new ArrayTest(width, height);

        long start, end;


        start = java.lang.System.currentTimeMillis();
        for (int i = 0; i < loops; i++) {
            a1.doMath(a2);
        }
        end = java.lang.System.currentTimeMillis();
        System.out.println("Elapsed time: " + (float)(end - start));
    }

}

在我的计算机中,这个C#代码运行大约5200ms,Java版本大约需要2800ms(!!!)。 我实际上期望.NET版本比Java版本运行得更快(或至少接近),但对此结果感到非常惊讶。

注意:我在Visual Studio外部运行了在发布模式下编译的.NET版本。

有人可以解释这个结果吗?这是真的吗? 我怎么能重写这段代码,以便C#.NET版本在执行速度上更接近Java?

[编辑]

嗯,我知道这不是一个真正有效的基准测试或公平的比较,但我怎么能重写这个代码,以便C#.NET版本在执行速度上更接近Java? 以任何形式尝试(直接操纵锯齿状数组,通过吸气剂等),但测试速度更慢。

[编辑2]

编辑测试,以便我有宽度和高度= 500,并且loop = 5000。 现在我的.NET版本大约为6300ms,Java版本大约为3700ms。当然,每个版本都会多次运行测试。

[编辑3]

刚刚使用平面数组而不是2D数组编写了类似的测试,这次.NET版本的运行速度与Java相同甚至更快。那是这样的吗? C#.NET的锯齿状数组比Java的多维数组慢?

2 个答案:

答案 0 :(得分:12)

每当你进行任何类型的基准测试或性能分析时,你都需要提出很多问题,并采用任何特定的结果(用Tanenbaum来解释),&#34;一公吨的盐&# 34。

但是......

我复制粘贴你的代码,这就是我得到的:

Compiler      Version   Timing
--------      -------   ------
MSVS 2012     C# 5      4448.0
Eclipse Luna  JRE 1.7    977.0

因此,Java程序的运行速度比C#程序快4.5倍。

我还运行了MSVS&#34;分析向导&#34;:

https://msdn.microsoft.com/en-us/library/dd264959.aspx

MSVS Profiler Summary Large picture

正如您可以从屏幕截图中看到的那样,&#34; Big Pig&#34;在这个配置文件中是ArrayTest.get_item(int32,int32),它耗尽了 NEARLY HALF 的执行时间:

enter image description here Large picture

答案 1 :(得分:1)

您无法根据单个实例判断性能。您需要为多个实例执行此操作。如果您想要有关绩效的具体答案,我建议您阅读quorablogSO