медленныеЕсть ли способ ускорить их? - PullRequest
3 голосов
/ 31 января 2011

В течение нескольких дней я включал и выключал проблему, в которой перечислены имена файлов, которые превышают ограничение Windows MAX_PATH. Я использую Visual Studio 2008 со всеми патчами, которые могу найти. Время определяется QueryPerformanceCounter и компанией.

Последняя проблема возникает в следующем коде:

    start = getTime();
    for( vector<wstring>::iterator it = files.begin(); it != files.end(); ++it )
    {
#if USE_COUT
            wcout << setw( 6 ) << it->length() << L": " << *it << endl;  // 1
#else
            wstring x( *it );
            wprintf( L"%6.6d: %s\n", it->length(), x.c_str() );          // 2
#endif
    }
    stop = getTime();

Приведенный выше цикл выполняется над вектором с 6755 записями со средней длиной строки 256 символов.

Код, который печатается через wcout, занимает примерно 52 секунды, чтобы отобразить вектор, используя цикл выше. Код, который использует wprintf, печатается за 1,2 секунды.

Если я сверну окно консоли, код printf будет выполняться примерно за 500 миллисекунд, а код wcout все равно займет около 40 секунд.

Я действительно пытался любить iostreams на протяжении многих лет, но ... я продолжаю бодать голову в этом вопросе скорости. В 1993/1994 гг. При использовании компилятора Borland OS / 2 у нас возникла похожая проблема со средой выполнения, для завершения которой потребовалось от 4 до 6 часов при использовании strstream, который работал примерно за 200 миллисекунд с помощью sprintf.

Какие-нибудь предложения, чтобы заставить меня изменить свое мнение о iostreams?

<ч /> Edit:
Все эти разговоры о смыве вызывают у меня любопытство.
Разве \n в строке printf функционально не совпадает с std::endl в том смысле, что оба приводят к выводу новой строки и сброса на выход?
IIRC, printf без \n не печатается на некоторых ОС до тех пор, пока не будет заполнен буфер или не очищен поток, включая Windows в прошлом.
Итак, если wprintf( "%6.6d: %s\n", length, string ) сбрасывается \n, почему wprintf не так медленно, как wcout?

Спасибо за ваши отзывы / мнения. Хотелось бы, чтобы 18 лет назад у меня было ТАК, когда я начал взламывать это.

Ответы [ 4 ]

8 голосов
/ 31 января 2011

Весьма вероятно, что терминатор строки std::endl вызывает узкое место в производительности, поскольку он очищает поток после ввода новой строки.Замените его на '\n' и std::wcout << std::flush в конце всего вывода.

start = getTime();
for( vector<wstring>::iterator it = files.begin(); it != files.end(); ++it )
{
        wcout << setw( 6 ) << it->length() << L": " << *it << '\n';  // 1
}
std::wcout << std::flush;
stop = getTime();
2 голосов
/ 31 января 2011
  wcout << setw( 6 ) << it->length() << L": " << *it << endl;  // 1

Один из способов ускориться - использовать "\n" вместо endl в цикле, так как endl - это больше, чем просто новая строка!

1 голос
/ 31 января 2011

Очень вероятно, что вы значительно ускорите свою работу, не сбрасывая поток на каждой итерации (используйте '\ n' вместо endl), хотя я предполагаю, что вы все равно найдете printf более быстрым.

Кстати, вы можете переместить setw за пределы вашего цикла.

1 голос
/ 31 января 2011

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

...