#cpp #c #windows #visual_cpp #console
Навеяно вопросом о том, что следует использовать - потоки или файловые функции, и что потоки обычно медленнее. Набросал тестовую программу (код ниже), испытал на Open Watcom и Visual C++ 2015. Сравниваются результаты вывода в консольное окно и в файл функциями для работы с потоками и с файлами. Чтоб работало со старым Watcom, для замера использовал clock(), попутно выяснилось, что в OW рекомендованная в упомянутом вопросе функция ios::sync_with_stdio() без параметров и obsolete, так что для этого компилятора ее убрал. Проверял под Windows 7 x64. Вопросов, собственно, два - а что делается у других компиляторов и операционных систем, и как, собственно, можно ускорить вывод - как консольный вообще, так и потоковый до уровня функций C. Есть ли какие-то варианты оптимизации? Чем обусловлен наблюдаемый разброс? Вот код: #include#include #include #include #include #include using namespace std; clock_t bench(void(*func)()) { clock_t start = clock(); func(); clock_t stop = clock(); return stop - start; } const int Count = 100000; vector dv; vector iv; FILE * outfile = 0; ofstream * outstream = 0; void printf_console() { for(int i = 0; i < Count; ++i) printf("%d %lf ",iv[i],dv[i]); } void printf_file() { for(int i = 0; i < Count; ++i) fprintf(outfile, "%d %lf ",iv[i],dv[i]); } void stream_console() { for(int i = 0; i < Count; ++i) cout << iv[i] << " " << dv[i] << " "; } void stream_file() { for(int i = 0; i < Count; ++i) *outstream << iv[i] << " " << dv[i] << " "; } int main(int argc, const char * argv[]) { for(int i = 0; i < Count; ++i) { dv.push_back(rand()/double(RAND_MAX)); iv.push_back(rand()); } outfile = fopen("test.dat","wt"); outstream = new ofstream("test.stream"); clock_t out_printf_console = bench(printf_console); clock_t out_printf_file = bench(printf_file); clock_t out_cout_sync = bench(stream_console); clock_t out_stream_file = bench(stream_file); ios::sync_with_stdio(false); clock_t out_cout_async = bench(stream_console); ios::sync_with_stdio(true); clock_t out_cout_rsync = bench(stream_console); cerr << "\n\n"; cerr << "printf console: " << setw(10) << out_printf_console << endl; cerr << "printf file : " << setw(10) << out_printf_file << endl; cerr << "stream sync console: " << setw(10) << out_cout_sync << endl; cerr << "stream async console: " << setw(10) << out_cout_async << endl; cerr << "stream rsync console: " << setw(10) << out_cout_rsync << endl; cerr << "stream file : " << setw(10) << out_stream_file << endl; delete outstream; fclose(outfile); } А вот результаты: Open Watcom: VC++ 2015: printf console: 16739 21806 printf file : 62 69 stream sync console: 16723 87678 stream async console: 16754 86899 stream rsync console: 16692 87254 stream file : 141 150 P.S. Удивляет что в общем случае VC++ бьет Open Watcom, а здесь - капитально ему проигрывает, в особенности при потоковом выводе в консоль.
Ответы
Ответ 1
@Harry, если интересны другие результаты. Windows 7 MinGW g++ 3.4.5 printf console: 4.43 printf file : 0.081 stream sync console: 18.262 stream async console: 1.093 stream rsync console: 1.176 stream file : 0.318 и в виртуалке VirtualBox на том же компе Linux avp-ubu1 3.13.0-85-generic #129-Ubuntu SMP Thu Mar 17 20:50:15 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux g++.real (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4 printf console: 0.11216 printf file : 0.072135 stream sync console: 0.152673 stream async console: 0.141306 stream rsync console: 0.141552 stream file : 0.070493 кстати о нем: avp@avp-ubu1:hashcode$ grep CPU /proc/cpuinfo model name : Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz model name : Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz model name : Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz model name : Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz avp@avp-ubu1:hashcode$ Время в секундах, поскольку глядя на сырую разницу clocks я заподозрил, что значение CLOCKS_PER_SEC в этих системах разное, короче вывод делается так: cerr << "printf console: " << setw(10) << (out_printf_console / (double)CLOCKS_PER_SEC) << endl; (остальные аналогично). P.S. разброс значений времени при разных запусках (для интереса я запускал раз пять) наблюдается, но похоже не больше 10%.Ответ 2
Первое. С таким подходом к измерению времени можно намерять такие интересные вещи, как погоду на Марсе, или влажность пяток певицы Монеточки. Современная многозадачная система может внезапно захотеть в фоновом режиме перекинуть пару-тройку страниц с диска в RAM - вот вам и разброс времени. Современный CPU может решить, что ему скучно работать на одной частоте, и культурненько ее снизить. Или поднять. Вон какое количество копий поломано об одно только измерение времени. Попробуйте повторить тесты из известной публикации, тогда ценность будет выше.Ответ 3
Разброс, возможно, обусловлен реализацией библиотеки. Конечно (ИМХО) более объективный результат - не одиночный вызов, а прогон серии. В качестве эксперимента можно попробовать stl извне, типа STLPORT или EASTL.
Комментариев нет:
Отправить комментарий