C # в два раза медленнее, чем Java в доступе к памяти с циклами? - PullRequest
10 голосов
/ 11 марта 2011

У меня есть две части кода, которые идентичны в C # и Java. Но Java один идет в два раза быстрее. Я хочу знать почему. Оба работают с одним и тем же принципом использования большой справочной таблицы для повышения производительности.

Почему Java работает на 50% быстрее, чем C #?

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 # имеет такой же тестовый код. Он измеряется с помощью секундомера вместо nanoTime () и использует Console.WriteLine вместо System.out.println(""), но это занимает как минимум вдвое больше времени.

Java занимает около 400 мс. Для компиляции в Java я использую флаг -server. В C # сборка настроена на выпуск без отладки или трассировки.

Что отвечает за разницу скоростей?

Ответы [ 2 ]

10 голосов
/ 11 марта 2011

Если вы синхронизируете сборку C # Debug или сборку Release из Visual Studio, вы получите очень вводящие в заблуждение сроки.Скомпилируйте в режиме Release и запустите из командной строки или в Visual Studio без отладки.То есть вместо запуска F5 нажмите Ctrl + F5 для запуска без отладки.

1 голос
/ 11 марта 2011

Возможно ли, что один из них последовательно обращается к последовательной памяти в массиве (т.е. к смежным элементам), в то время как другой подпрыгивает повсюду? Если это так, то один из них получит серьезное усиление от процессора, предварительно выбирающего смежные элементы массива, а другой - нет.

Тем не менее, когда вы делаете симулятор покерной руки, вы можете попробовать симуляцию Монте-Карло. Результаты розыгрыша дойдут далеко до того, как вы попробуете все возможные комбинации из 7 карт.

Если вы используете объект колоды карт, просто зафиксируйте стрелки и доску на их текущих значениях, затем выньте случайную доску из колоды, перемешайте, повторите x раз. Значения должны сходиться по фактическим вероятностям задолго до того, как вы перечислили каждую возможность.

...