Печать C ++ на терминал намного медленнее при добавлении флага `g ++` '`-std =`? - PullRequest
0 голосов
/ 01 марта 2019

Сводка

У меня есть этот код C ++:

#include <iostream>
#include <chrono>

int main() {
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();

    for (int counter = 0; counter < 80000;) {
        std::printf("%d\n", counter++);
    }

    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

    std::cout << std::endl << "Time difference (sec) = " << (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000000.0 << std::endl;

    std::cin.get();
    return 0;
}

При запуске кода после компиляции с g++ Source.cpp -O3 время выполнения обычно составляет около 25 секунд на моей машине.Однако, если я использую g++ Source2.cpp -std=c++14 -O3 для компиляции, время выполнения, которое я получаю, превышает 90 секунд .

Подробнее

Я компилирую с g++ версия 8.2.0, которая определяет __cplusplus как 201402L.Следовательно, по умолчанию он должен компилироваться в соответствии со стандартом C ++ 14.

Поэтому кажется странным, что код будет работать намного медленнее, когда я добавлю флаг -std=c++14.Я также заметил, что код работает так же медленно, если я использую -std=c++11, поэтому кажется, что проблема заключается в использовании -std=.

NB 1: Я использую printf()вместо cout в цикле, потому что я знаю, что первый быстрее.

NB 2: Мой вопрос полностью отличается от Код работает медленнее с g ++ -std =c ++ 0x , хотя название может звучать похоже.

Обновление

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

Я также запускал код в разных терминалах в Windows: cmd, PowerShell, cmder.Я обнаружил, что, хотя точное время выполнения на каждом терминале различно, код без флага -std=, как правило, по-прежнему работает как минимум вдвое быстрее .

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

Итак, конкретный вопрос:

Почему добавление флага замедляет выполнение кода при печати кода на терминале?

Обновление 2

После выполнения дополнительных тестов я понял, что разницанезначительно при использовании терминала, который распечатывает код за короткое время (несколько секунд или меньше секунды).

Кажется, что разница во времени выполнения, которую я получал, свойственна средемоей машины и может не воспроизводиться.

Тем не менее, идеи, предоставленные Майклом в его ответе и комментариях, ценны и могут помочь объяснить проблемыс подобной природой сталкиваются другие.

1 Ответ

0 голосов
/ 01 марта 2019

Различия исключительно из-за терминала.Обе альтернативы пишут в терминал, который должен вести историю прокрутки и рисовать пиксели написанных символов.Терминал работает намного сложнее, чем короткий тест, который выплевывает только символы ASCII.

На самом деле ваш терминал (и / или ОС) работают очень медленно.Я запустил ту же самую программу (скомпилированную с gcc-8.2.0) на терминале MAC, и она работала 0,175374 секунды, один раз и 0,186559 в другой раз.Без сбора значительного количества статистических данных я не мог видеть никакой разницы с -std=c++14 и без него.

Кажется, проблема связана с очень медленным терминалом (более чем в 100 раз медленнее терминала MAC), а не с самим кодом.Скорее всего, ваш терминал становится медленнее, когда собирает историю, поэтому во второй раз он работает медленнее (независимо от флагов компиляции).

Редактирование после просмотра обновленного вопроса:

Возможночто по умолчанию используется значение -std=gnu++14, которое выполняет некоторую нестандартную оптимизацию, которая ускоряет работу терминала.Когда вы передаете -std=c++14 расширение gnu выключено.

Для справки смотрите компиляция с std c11 ... .В соответствии с ним -std=c++14 означает, что _GNU_SOURCE больше не определен, и может использоваться другая реализация printf .

...