Pull to refresh

Comments 17

Была у меня мысль вернуться к этой задаче, повода не было. Теперь есть :)

И кстати, для замеров лучше использовать time, это точнее

FizzBuzz in C, Ansi-style

Я так и не смог понять, что имеется в виду под "ansi style". Автор местами использует фичи C99, но при этом валит объявления переменных в одну кучу в начале функции и избегает инициализации... С const тоже винегрет: где-то есть, где-то нет.

Это стандартный заголовок Eclipse.

Лень этого автора очевидна

Такое ощущение, что он и с fwrite мог все вырезать. Не вижу здесь нигде использование переменных из сторонних источников

Одно принципиальное замечание - убирать строки с fwriteиз программы нельзя, потому что в этом случае оптимизатор может смело выкинуть всю работу с буфером, то есть практически весь код. Отсюда и получается магический результат в 0.001 сек. Сениоры такое знают ;)

Уже выше написали

И оставлять нельзя, это может повлиять на замеры времени. Я обычно помещаю fwrite в заведомо невыполнимую ветвь кода, чтонить типа
if argv[1] == "5" && result.size() == 100 {
fwrite(...)
}

Я просто перенаправлял вывод в /dev/null, это конечно чуть добавляет, но незначительно.
Думаю, что вполне можно допустить, что при выводе в /dev/null все использованное программой время - вычисления, ну еще и немного времени kernel'а при многопоточного варианта, но это тоже можно считать в общие расходы программы (без I/O)

Может кто-то объяснить, что даёт длина массива l[30], вместо l[15]?

тут результат считается сразу в десятичном виде. И прибавить 3 к предпоследнему разряду это одна команда. А прибавить 15 это две команды - прибавить 5 и прибавить 1 с переносом.

Ну если оптимизировать, то должна быть поддержка многопоточных вычислений. Иначе хорошо читаемый код сеньора при добавлении пары операторов побьёт этот нечитаемый код даже по производительности.

Это немного другая задача. На codegolf FizzBuzz бесконечный, а тут ограничен миллиардом, что позволяет дополнительные оптимизации

Там немного другая оптимизация. Просто вывод fwrite по 30 строк в миллиарде требует почти 1.5 сек. Многопоточность там разрешена и достаточно 3 потоков, чтобы получить максимальную скорость вывода.

Если там что есть быстрее (20G/sec у xiver77), то это уже оптимизация ввода/вывода. Ну и алгоритмически неинтересна. В этой статье собственно скорость не главное. Тут вся хитрость в алгоритме.

Даже если провести очевидные оптимизации сеньорского кода - использовать в одной команде деление с остатком (ассемблерный код, наверно) и убрать деление до 0 в myitoa и найти другой критерий останова.

    do {
        *--cur = number % 10 + '0';
        number /= 10;
    } while (number != 0);

то все равно мой код будет быстрее - в нем для получения каждого байта кода вывода используется "+1" или "+3" и ">9", что гораздо быстрее деления на 10.

Итак, чтобы победить этот мой изящный говнокод, сеньорам нужно придумать что-то умное или хитрое. Просто так парой операторов дело провернуть не получится.

Sign up to leave a comment.

Articles