2015-10-22 3 views
1
void perfprint(unsigned int count) 
{ 
    char a[100] = "fosjkdfjlsjdflw0304802"; 
    for(unsigned int i = 0;i<count;++i) 
    { 
     printf("%s", a); 
    } 
} 

void perfcout(unsigned int count) 
{ 
    char a[100] = "fosjkdfjlsjdflw0304802"; 
    for(unsigned int i = 0;i<count;++i) 
    { 
     cout << a; 
    } 
} 

Окружающей среду: C++, VS 2010, Windows 7, 32-бит, Core-i7, 4 Гб, 3,40 ГГцPrintf против производительности соиЬ

Я проверил обе функцию с count = 10000 для 5 раз каждых. Измерение производительности с использованием QueryPerformanceCounter.

perfprint>~850 миллисекунды (Avg 5 серий)

perfcout>~9000 миллисекунды (Avg 5 серий)

Означает ли это Printf является ~10x быстрее, чем соиЬ

Edit:

С/Ox,/Ot, Отладочная информация отсутствует в сборке выпуска

и std::ios_base::sync_with_stdio(false); в perfcout методом, результат одинаков для cout т.е. ~9000 millisecs

Edit 2:

В заключение следует сказать, cout быстрее, чем printf. Причина наблюдений выше была обусловлена ​​выходом консоли. При перенаправлении вывода в файл все обернулось на голову!

+1

Нет, это означает, что вы не понимаете, как синхронизируются iostreams и как это влияет на их скорость. Попробуйте вызвать 'std :: ios_base :: sync_with_stdio (false)' в начале 'perfcout'. – user657267

+0

Технически дубликат http://stackoverflow.com/questions/9371238/why-is-reading-lines-from-stdin-much-slower-in-c-than-python – CodeMouse92

+0

Можете ли вы запустить тест при добавлении std: : ios_base :: sync_with_stdio (ложь)? –

ответ

5

Я не имею VS 2010 установлен больше, но я сделал быстрый тест с VS 2013 и 2015 годами я немного изменил свой код, чтобы уменьшить дублирование, и включает в себя код синхронизации, давая это:

#include <iostream> 
#include <cstdio> 
#include <chrono> 
#include <string> 

template <class F> 
int perf(F f) { 
    using namespace std::chrono; 

    const int count = 1000000; 
    char a[100] = "fosjkdfjlsjdflw0304802"; 

    auto start = high_resolution_clock::now(); 
    for (unsigned i = 0; i < count; i++) 
     f(a); 
    auto end = high_resolution_clock::now(); 

    return duration_cast<milliseconds>(end - start).count(); 
} 

int main() { 
    std::cerr << "cout: " << perf([](char const *a) { std::cout << a; }) << "\n"; 
    std::cerr << "printf: " << perf([](char const *a) { printf("%s", a); }) << "\n"; 
} 

С отключенной оптимизацией cout показался немного быстрее (например, 358 мс против 460 для printf), но измерение скорости с выключенной оптимизацией довольно бессмысленно.

С оптимизацией включен cout выиграл еще больший запас (191 мс против 365 мс за printf).

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

+0

Скорость драйвера консоли применима как к 'printf', так и к' cout' – deepdive

+1

@deepdive. Это правда, но могут быть реализованы различные функции, так что один или другой эффект значительно влияет. Например, одна функция может подготовить буфер и отправить его на консольный хост за один вызов, в то время как другой может отправлять каждый байт по отдельности. Этот пример не выбирается случайным образом; когда stdout подключен к стандартной консоли Windows 'cout <<" Hello "" приводит к 5 отдельным межпроцедурным вызовам, по одному для каждого байта, тогда как 'printf ("% s "," Hello ")' приводит к одному IPC. – bames53

+0

И если вы запустите программу из mintty в Windows вместо cmd.exe, проблема исчезнет. Поскольку mintty не делает вещи проходить через консоль Windows вместо ужасной производительности IPC, вы получаете эффективное поведение буферизации файлов. – bames53

Смежные вопросы