Поигрался с размером буфера, никаких изменений не заметил. 5МБ буфера и 1 чанк выдали 4.8 сек, против 3.4 при 35000 чанках. Компиляция без -pthread и замена fwrite на fputs_unlocked тоже ничего не дали.
> Сомневаюсь, что это дает какой-то выигрыш, поскольку fwrite() уже буферизован.
Я тоже так думал, но был удивлен, когда это дало примерно 1 сек выигрыша. Думаю передавать много маленьких буферов в fwrite хуже, чем буферы побольше.
Преверить можно установив константу CHUNK_COUNT в 1.
> В customprint.c нет деления по модулю
Он был нужен мне в инкременте. Как говорится сам добавил, сам же и соптимизировал.
Спасибо за задачку, было интересно подумать над ней!
Я взял за основу customprint.c (работает примерно 9.2 сек на моей машине), и применил следующие идеи:
— Экономить на вызовах fwrite. Для этого процессим числа в блоках, кратных 15. Я остановился на 35000 блоках. Дает небольшой выигрыш.
— Поддерживать текущее число в виде строки и эмулировать инкремент. Ускоряет за счет того, мы не всегда итерируемся по всем цифрам текущего числа (гораздо чаще инкрементится только последняя цифра).
— Экономить на инкрементах. Для этого заметим, что если после числа мы следующим выведем слово, то можно инкрементить на сразу 2, если два слова — то на 3.
— Мелкие микрооптимизации, которые почти ни на что не повлияли (например, полное избавление от деления и взятия по модулю при инкременте)
Итоговое решение работает за примерно 3.4 сек на моей машине (ссылка)
Тем не менее слово «неадекватно» гораздо чаще применяется в виде оскорбления и применение его в работе по отношению к коду созданному другим человеком может уменьшить желание следовать этому комментарию.
Подобная атмосфера не способствует взаимопониманию и продуктивности.
Полностью с вами согласен, субъективность восприятия людей все меняет. Возможно мне не стоило поднимать эту бессмысленную дискуссию о степени резкости одного слова, но мой глаз за него зацепился в изначальном комментарии.
есть отношения подавления и силы и hostile environment
Быть в позиции силы не означает, что ее нужно использовать, но все же у ревьюера она есть, и это факт, о котором стоит помнить.
тогда любые замечания будут восприниматься в позитивном ключе
Не могу согласиться со словом «любые», опять-таки это слишком субъективно и нужно помнить что разные люди воспринимают жесткую критику по-разному.
P.S.
Вот это и есть проблема с чрезмерной толерантностью.
Чисто из интереса: считаете ли фразу, которые я предложил как коменты в код-ревью излишне толерантными? Такой же вопрос к общему стилю моих комментариев в этом треде.
Думаю все-таки очень важно следить за лексиконом во время код-ревью. Даже такие слова как «неадекватно» могут выглядеть чересчур резкими. Помните, что вы и без этого в позиции силы, аппрувал кода зависит от вас и нет нужды дополнительно демонстрировать эту силу.
Я бы переформулировал эту фразу более нейтрально: «Этот файл открывается в цикле, это может сильно сказаться на сложности/производительности кода». Желательно дополнить это еще советом (но не указанием, автор может придумать что-то лучше чем вы) о том, как этот код можно улучшить. Например: «Попробуйте переписать код так, чтобы открыть файл один раз перед циклом и переиспользовать дескриптор»
Такой же подход применяется при тестировании олимпиадных задач. Пишется модельное решение и тестируется вручную. Затем генерируются тесты (генератором), и правильные ответы (модельным решением). После этого, результаты, полученные с помощью модельного тестирования, сравниваются с разультатами участника при помощи чекера (а в простейшем варианте при помощи diff-а).
С другой стороны, те же 99% программистов будут использовать vector, а не массив и ошибка будет найдена в рантайме.
Стандарт C++ гарантирует, что лишь vector::at (насколько часто он встречается?) выбросит исключение (пруф). В случае же с vector::operator [] будет обычный UB.
Если что, использовал это:
Я тоже так думал, но был удивлен, когда это дало примерно 1 сек выигрыша. Думаю передавать много маленьких буферов в fwrite хуже, чем буферы побольше.
Преверить можно установив константу CHUNK_COUNT в 1.
> В customprint.c нет деления по модулю
Он был нужен мне в инкременте. Как говорится сам добавил, сам же и соптимизировал.
Я взял за основу customprint.c (работает примерно 9.2 сек на моей машине), и применил следующие идеи:
— Экономить на вызовах fwrite. Для этого процессим числа в блоках, кратных 15. Я остановился на 35000 блоках. Дает небольшой выигрыш.
— Поддерживать текущее число в виде строки и эмулировать инкремент. Ускоряет за счет того, мы не всегда итерируемся по всем цифрам текущего числа (гораздо чаще инкрементится только последняя цифра).
— Экономить на инкрементах. Для этого заметим, что если после числа мы следующим выведем слово, то можно инкрементить на сразу 2, если два слова — то на 3.
— Мелкие микрооптимизации, которые почти ни на что не повлияли (например, полное избавление от деления и взятия по модулю при инкременте)
Итоговое решение работает за примерно 3.4 сек на моей машине (ссылка)
Полностью с вами согласен, субъективность восприятия людей все меняет. Возможно мне не стоило поднимать эту бессмысленную дискуссию о степени резкости одного слова, но мой глаз за него зацепился в изначальном комментарии.
Быть в позиции силы не означает, что ее нужно использовать, но все же у ревьюера она есть, и это факт, о котором стоит помнить.
Не могу согласиться со словом «любые», опять-таки это слишком субъективно и нужно помнить что разные люди воспринимают жесткую критику по-разному.
P.S.
Чисто из интереса: считаете ли фразу, которые я предложил как коменты в код-ревью излишне толерантными? Такой же вопрос к общему стилю моих комментариев в этом треде.
Я бы переформулировал эту фразу более нейтрально: «Этот файл открывается в цикле, это может сильно сказаться на сложности/производительности кода». Желательно дополнить это еще советом (но не указанием, автор может придумать что-то лучше чем вы) о том, как этот код можно улучшить. Например: «Попробуйте переписать код так, чтобы открыть файл один раз перед циклом и переиспользовать дескриптор»
Точно также рассуждало руководство СССР, когда решило открыть Семипалатинской полигон. О последствиях говорить смысла нет.
Мне сразу же вспомнился другой рассказ о создании компилятора C++. До сих пор перечитываю эту статью, очень мотивирует.
Стандарт C++ гарантирует, что лишь
vector::at
(насколько часто он встречается?) выбросит исключение (пруф). В случае же сvector::operator []
будет обычный UB.