10

我有两段在 C# 和 Java 中相同的代码。但是 Java 的速度要快两倍。我想知道为什么。两者都使用相同的原理,即使用大查找表来提高性能。

为什么 Java 比 C# 快 50%?

Java代码:

    int h1, h2, h3, h4, h5, h6, h7;
    int u0, u1, u2, u3, u4, u5;
    long time = System.nanoTime();
    long sum = 0;
    for (h1 = 1; h1 < 47; h1++) {
        u0 = handRanksj[53 + h1];
        for (h2 = h1 + 1; h2 < 48; h2++) {
            u1 = handRanksj[u0 + h2];
            for (h3 = h2 + 1; h3 < 49; h3++) {
                u2 = handRanksj[u1 + h3];
                for (h4 = h3 + 1; h4 < 50; h4++) {
                    u3 = handRanksj[u2 + h4];
                    for (h5 = h4 + 1; h5 < 51; h5++) {
                        u4 = handRanksj[u3 + h5];
                        for (h6 = h5 + 1; h6 < 52; h6++) {
                            u5 = handRanksj[u4 + h6];
                            for (h7 = h6 + 1; h7 < 53; h7++) {
                                sum += handRanksj[u5 + h7];
    }}}}}}}
    double rtime = (System.nanoTime() - time)/1e9; // time given is start time
    System.out.println(sum);

它只是列举了所有可能的 7 张牌组合。C# 版本是相同的,除了最后它使用 Console.writeLine。

查找表定义为:

static int handRanksj[];

它在内存中的大小约为 120 兆字节。

C# 版本具有相同的测试代码。它是用 Stopwatch 而不是 nanoTime() 来测量的,并使用Console.WriteLine而不是,System.out.println("")但它至少需要两倍的时间。

Java 大约需要 400 毫秒。对于 java 中的编译,我使用 -server 标志。在 C# 中,构建设置为在没有调试或跟踪定义的情况下发布。

速度差异的原因是什么?

4

2 回答 2

10

如果您正在计时 C# Debug 构建或 Visual Studio 中的 Release 构建,您将获得非常误导的计时。在发布模式下编译并从命令行运行或在 Visual Studio 中运行而无需调试。即不按F5运行,而是按Ctrl+F5不调试运行。

于 2011-03-11T17:27:41.447 回答
1

是否有可能其中一个正在按顺序访问数组中的顺序内存(即相邻元素),而另一个正在到处弹跳?如果是这样,它们中的一个会从处理器预取相邻数组元素中获得显着提升,而另一个则不会。

也就是说,在做扑克手模拟器时,您可能想尝试蒙特卡洛模拟。在你尝试了所有可能的 7 张牌组合之前,手牌的结果会收敛很多。

如果您使用一副纸牌对象,只需将手和棋盘固定在当前值,然后从牌堆中随机分配一个棋盘,洗牌,重复 x 次。早在您列举出所有可能性之前,这些值就应该收敛于实际概率。

于 2011-03-11T17:18:02.083 回答