С# вдвое медленнее, чем Java в доступе к памяти с помощью циклов?

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

Почему Java идет на 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 комбинаций карт. Версия С# идентична, но в конце она использует Console.writeLine.

Поисковая таблица определяется как:

static int handRanksj[];

Его размер в памяти составляет около 120 мегабайт.

Версия С# имеет тот же тестовый код. Он измеряется с помощью секундомера вместо nanoTime() и использует Console.WriteLine вместо System.out.println(""), но требуется как минимум удвоить время.

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

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

Ответ 1

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

Ответ 2

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

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

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