2011-01-31 2 views
3

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

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

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 часов, чтобы завершить использование потока stream, который выполнялся примерно через 200 миллисекунд с помощью sprintf.

Любые предложения, чтобы заставить меня изменить свое мнение о iostreams?


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

Благодарим Вас за отзыв. Хотелось бы, чтобы у меня было так 18 лет назад, когда я начал взламывать это.

+1

Это может быть реальная консоль, которая медленная, а не ваша программа. У вас есть ускорение, если вы перенаправляете вывод в файл 'yourprogram> file.txt' или записываете в фактический файл вместо wcout? – nos

+1

Что происходит с производительностью, если вы используете '\ n' вместо' endl'? –

+0

@ nos: Это немного ускорилось. До тех пор, пока вы не перенаправляетесь на 2 секунды. Возможно, мне придется работать в пакетном файле, чтобы неграмотный компьютер, который будет его использовать, не должен прибегать к перенаправлению командной строки :) Спасибо – JimR

ответ

8

Очень вероятно, что ограничитель линии вызывает узкое место в производительности, поскольку он смывает поток после помещения новой строки. Обмениваем его на '\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(); 
+0

Спасибо, это немного ускорилось. – JimR

2
wcout << setw(6) << it->length() << L": " << *it << endl; // 1 

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

+0

Это ускорилось от некоторых Наваза, спасибо. – JimR

1

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

+0

Программа дает некоторую итоговую информацию в конце, что и прежде всего хочет видеть пользователь. Имена файлов есть, поэтому он может обратиться к ним, если это необходимо. Размер прокрутки для консоли установлен на max (9999 строк), и это то, что он хочет, поэтому ... Вот что он получает. – JimR

1

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

Возможно, вы также можете перемещать setw вне своей петли.

+1

Перемещение 'setw' вне цикла будет означать, что оно будет применено только к первой итерации. –