[flame] printf vs стримы

Werdna

#include <sstream>
ни при каких обстоятельствах нельзя использовать идиотские стрингстримы.
только snprintf, его не может не быть.

kokoc88

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

Werdna

Ты бы хоть обосновывал свои утверждения, чтобы тебе можно было возразить.
Медленный. (мерь сам, я это делал года 4 назад)
Реализация чаще всего кривая и течет, валгринд ругается.
Если уж так охота писать эти палочки <<>>, сделай свою реализацию.
Ещё у snprintf можно указать формат, в очевидном и понятном виде.

Serab

Ещё у snprintf можно указать формат, в очевидном, понятном и небезопасном виде.
А еще преждевременная оптимизация — корень зла, да.

bleyman

Медленный. (мерь сам, я это делал года 4 назад)
Если в твоей программе конвертация чисел в строки является критичным по скорости местом, то скорее всего ты дурилка и она им не является.
Реализация чаще всего кривая и течет, валгринд ругается.
Пруфпик или не было.
Если уж так охота писать эти палочки <<>>, сделай свою реализацию.

Если у тебя нет очень серьёзных причин переписывать стандартную функциональность, а так же твёрдой уверенности в том, что твой велосипед будет лучше (а не в те же пять раз медленней чем если ручками делать ни в коем случае этого делать нельзя, именно это называется "плюсоёбством".
А уж за подобные советы нубам надо просто отрезать репродуктивные органы.

Marinavo_0507

Если в твоей программе конвертация чисел в строки является критичным по скорости местом, то скорее всего ты дурилка и она им не является.
А типа экспорт чего-то числового в большой xml?

kokoc88

Медленный. (мерь сам, я это делал года 4 назад)
У меня почему-то работает точно так же как и семейство printf. Видимо, ты использовал его неправильно. (Например, им можно пользоваться так, чтобы память каждый раз не размещалась.)
Реализация чаще всего кривая и течет, валгринд ругается.
Это неправда. Приведи пример кода, который течёт.
Ещё у snprintf можно указать формат, в очевидном и понятном виде.

Зато он совершенно небезопасен с точки зрения типизации.

kokoc88

А типа экспорт чего-то числового в большой xml?
Там ботлнеком будет запись в файл, а не преобразование чисел.

tamusyav

Медленный. (мерь сам, я это делал года 4 назад)
У меня почему-то работает точно так же как и семейство printf. Видимо, ты использовал его неправильно. (Например, им можно пользоваться так, чтобы память каждый раз не размещалась.)
В любом случае этот пункт для ТС некритичен.
PS: (2)Пардон, мало сцитировал - надеюсь, теперь понятно.

kokoc88

В любом случае этот пункт для ТС некритичен.
Ты о чём вообще?

Werdna

А уж за подобные советы нубам надо просто отрезать репродуктивные органы.
Я по твоим губам надавал своей мохнатой дубинкой.
ща тест сделаю, чтобы тебе показать.

Werdna

В обоих случаях делаем одно и то же. Если не делать кастинга к стрингу, то результат ещё интересней: snprintf тупо работает на два порядка быстрее. Проверь.
 
-laptop:~/2010-02/xxx$ cat a.cpp
#include <stdio.h>
#include <string>

int main
{
std::string s;
unsigned i = 10000000;
while (i--)
{
char buf[64];
snprintf(buf, 64, "%d", i);
s = buf;
}
return 0;
}
-laptop:~/2010-02/xxx$ cat b.cpp
#include <sstream>

int main
{
std::string s;
unsigned i = 10000000;
while (i--)
{
std::ostringstream strm;
strm << i;
s = strm.str;
}
return 0;
}
-laptop:~/2010-02/xxx$ time ./a

real 0m3.410s
user 0m3.400s
sys 0m0.004s
-laptop:~/2010-02/xxx$ time ./b


real 0m15.753s
user 0m15.753s
sys 0m0.000s

Я не делаю преждевременных оптимизаций. Также я не делаю преждевременных торможений.

salamander

Там ботлнеком будет запись в файл, а не преобразование чисел.
Правда что ли?
 swan ~/tmp/2 $ cat t1.c
#include <stdio.h>

int main(void)
{
int i;
for (i = 0; i < 10000000; i++)
printf("%d\n", i+10000000);
return 0;
}
swan ~/tmp/2 $ cat t2.c
#include <stdio.h>

const char *s = "10000001\n";
int l = 9;

int main(void)
{
int i;
for (i = 0; i < 10000000; i++)
fwrite(s, sizeof(char l, stdout);
return 0;
}
swan ~/tmp/2 $ time ./t1 >r1

real 0m2.187s
user 0m1.980s
sys 0m0.205s
swan ~/tmp/2 $ time ./t2 >r2

real 0m0.637s
user 0m0.427s
sys 0m0.210s
swan ~/tmp/2 $

Итого вывод работает менее 0.637 секунды. Значит из 2.187 секунд 1.55 было балгополучно съедено на "преобразование чисел".

agent007new

Ну да, а после таких любителей printf'ов сидишь и отлавливаешь падения

zya369

ты сравниваешь производительность << или производительность конструкторов?
навскидку
 
:~/garb$ cat d.cpp
#include <sstream>

int main
{
std::string s;
std::ostringstream strm;
unsigned i = 10000000;
const std::string s0 = "";
while (i--)
{
strm.str(s0);
strm << i;
s = strm.str;
}
return 0;
}
:~/garb$ time ./d

real 0m2.524s
user 0m2.520s
sys 0m0.000s
:~/garb$ time ./a

real 0m1.827s
user 0m1.770s
sys 0m0.010s


медленнее, конечно, ощутимо, но не на порядок уже

kokoc88

Правда что ли?
Правда, потому что твой тест, скорее всего, неправильный. Просто для примера:
#include <windows.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
DWORD start = ::GetTickCount;
FILE* f = ::fopen("test1.txt", "w");
for (int i = 0; i < 10000000; i++)
::fprintf(f, "%d\n", 10000000+i);
::fclose(f);
::printf("time: %f\n", (::GetTickCount-start)/1000.0);

start = ::GetTickCount;
f = ::fopen("test2.txt", "w");
for (int i = 0; i < 10000000; i++)
::fwrite("10000001\n", sizeof(char 9, f);
::fclose(f);
::printf("time: %f\n", (::GetTickCount-start)/1000.0);
return 0;
}

time: 5.313000
time: 6.156000
Хотя полученное в данном случае время - не показательное, просто тесты всегда показывают разброс до нескольких секунд. И конечно, просто запись в файл почти всегда быстрее форматирования числа и записи в файл.

salamander

твой тест, скорее всего, неправильный
В таком случае говори, в чем его неправильность.
Свой пример я компилировал gcc 4.4.2 с опциями -W -Wall -O2. Запускал под линуксом. Результаты я уже привел в предыдущем посте.
Сейчас скомпилировал твой пример и запустил несколько раз. Компилировал VS 2005. Сначала в Debug, потом в Relese. Полученное время:
Debug:
time: 5.875000
time: 1.594000

Release:
time: 4.109000
time: 1.328000

От запуска к запуску оно изменяется слабо.
Свой и твой пример я запускал под разными ОС на разных машинах, но результат у меня получается одного типа. Так что давай рассказывай, как у тебя так получилось, что fwrite работает дольше fprintf.
И конечно, просто запись в файл почти всегда быстрее форматирования числа и записи в файл.
Да, как раз на форматирование числа оно и работает быстрее. Собственно эту разность мы и пытаемся померить, сравнивая запись в файл и запись в файл с форматированием. И еще раз замечу: в приведенных тобой результатах запись в файл работает заметно медленнее чем запись в файл плюс форматирование. Такого быть не должно.

kokoc88

В обоих случаях делаем одно и то же. Если не делать кастинга к стрингу, то результат ещё интересней: snprintf тупо работает на два порядка быстрее. Проверь.
Конечно же ты прав на счёт того, что printf-ы будут работать быстрее. (А я был не совсем прав, когда сказал что точно так же.) Они много чего не делают из того, что делают iostreams и во время таких простых тестов будут всегда впереди по производительности. (Ну разве что есть хитрости, которые позволяют избежать такой драматической разницы, я имею ввиду методы rdbuf tellp seekp Теперь прочитай свои же слова, на них тебе и возражают:
ни при каких обстоятельствах нельзя использовать идиотские стрингстримы.
Кроме этого есть же ещё куча вещей типа boost::format, где сохраняется удобство форматирования при сохранении безопасной типизации.

kokoc88

Так что давай рассказывай, как у тебя так получилось, что fwrite работает дольше fprintf.
Это надо спросить у моей ОС (винда XP, аптайм около недели, кэш на чтение-запись видимо весь забит). Получилось просто: запустил тест раз 10, наверное.
И еще раз замечу: в приведенных тобой результатах запись в файл работает заметно медленнее чем запись в файл плюс форматирование. Такого быть не должно.
Как это не должно? Ключевое слово здесь: запись в файл. Конечно, когда у тебя наготове пустой кэш, ситуация может быть далеко не в пользу форматирования чисел.

kazakova_777777

Ок, с конвертацией разобрался.
Еще 1 глупый вопрос, подскажите плз вкратце.
Как передать строку из главной программы в файл формы ?
Просто указание строки из главного модуля не распознается

salamander

Конечно, когда у тебя наготове пустой кэш, ситуация может быть далеко не в пользу форматирования чисел.
Во-первых, там файлики по 100 мегабайт. Это все же больше дикового кэша. Увеличил в 10 раз:
time: 44.562000
time: 13.313000

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

kazakova_777777

Там нельзя сразу же переменные форматированные печатать ?
Типа Form1::label1->Text, только не Text, а объект какой-нибудь.
Просветите плз

kokoc88

Во-первых, там файлики по 100 мегабайт. Это все же больше дикового кэша.
В моей винде дисковый кэш растягивается до гигабайта. Так что моё мнение пока что остаётся таким же: в реальной системе ботлнеком будет ввод-вывод, а не форматирование чисел.

Marinavo_0507

Ну во-первых, кто говорит, что экспорт пойдёт обязательно в файл? Или что результат не влезет в кэш?

Dasar

Ну во-первых, кто говорит, что экспорт пойдёт обязательно в файл? Или что результат не влезет в кэш?
с таким же успехом - а почему не на дискетку, или не на перфокарты?
речь все-таки о реальности, а не о вырожденных случаях...
а в реальности - узким местом будет винт, а не форматирование чисел.

Marinavo_0507

а в реальности - узким местом будет винт
ну некоторые памяти не жалеют

kokoc88

Ну во-первых, кто говорит, что экспорт пойдёт обязательно в файл? Или что результат не влезет в кэш?
Под чем-то большим обычно понимают что-то большое. А не то, что надо в памяти перегнать, когда разница между iostreams/printf вообще заметна не будет. Приводи примеры, чтобы можно было более детально обсуждать. Если 1 из 10000 задач, с которыми мы сталкиваемся, потребует массового преобразования чисел в строки, то здесь самописная функция всех порвёт. Но пользоваться самописной функцией во всех остальных 9999 задачах просто глупо.

Marinavo_0507

> Под чем-то большим обычно понимают что-то большое.
Ну например, если вывод длится секунду, а результат около 15М - это большое? Вроде не очень, но не в том случае, если захочется анализировать этот вывод несколько раз в минуту.

Dasar

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

salamander

В моей винде дисковый кэш растягивается до гигабайта.
20 гигабайт:
time: 959.391000
time: 358.047000

Не в дисковом кэше тут дело, тут именно printf тормозит.
Так что моё мнение пока что остаётся таким же: в реальной системе ботлнеком будет ввод-вывод, а не форматирование чисел.
Ну на аргумент "А я все равно не верю!" мне возразить нечего.

kokoc88

Не в дисковом кэше тут дело, тут именно printf тормозит.
Да не вопрос, пусть printf тормозит. Я согласен.
Ну на аргумент "А я все равно не верю!" мне возразить нечего.
Аргумент такой: "в реальной системе ботлнеком будет ввод-вывод, а не форматирование чисел". Тебе на него есть что возразить?

Werdna

Кроме этого есть же ещё куча вещей типа boost::format, где сохраняется удобство форматирования при сохранении безопасной типизации.
Буст вообще на помойку. Весь и сразу.

asvsergey

А std::tr1?

Serab

Я не делаю преждевременных оптимизаций. Также я не делаю преждевременных торможений.
Это все отговорки, твои действия — это именно преждевременная микрооптимизация.

Werdna

А std::tr1?
я использую.
со знанием и пониманием можно использовать всё. Другое дело, что не надо гнаться за "модными" технологиями ради самой моды.

Werdna

Это все отговорки, твои действия — это именно преждевременная микрооптимизация.
В чем оптимизация?

asvsergey

со знанием и пониманием можно использовать всё. Другое дело, что не надо гнаться за "модными" технологиями ради самой моды.
Можно вообще не гоняться за технологиями, все равно не поспеть :)
Само собой знание и понимание не приходит, и сложно ждать знания и понимания чего либо от того, кто этим не пользуется.

Werdna

сложно ждать знания и понимания чего либо от того, кто этим не пользуется.
А что в стрингстримах знать?
Я посмотрел, один раз. Ещё на буст лексикал каст посмотрел. Померил, решил что мне эти рюшечки не нужны ни под каким соусом.

asvsergey

Я про весь буст, а лексикал каст, в частности, иногда помогает бестрее написать код.

salamander

Аргумент такой: "в реальной системе ботлнеком будет ввод-вывод, а не форматирование чисел". Тебе на него есть что возразить?
Это не аргумент, это утверждение. На данный момент являющееся голословным. Между прочим, с него наш разговор и начался ( ) Так что навозражал я на него уже достаточно.

Werdna

Я про весь буст, а лексикал каст, в частности, иногда помогает бестрее написать код.
И не важно что он будет дольше компилироваться и выполняться.
А я использу snprintf/strftime/..., и для парсинга те же аналоги, у меня всё всегда работает. Пишу тоже быстро, что я желаю не так?

kokoc88

Так что навозражал я на него уже достаточно.
Навозражал ты программой, которая будучи запущена с эксклюзивным доступом к винту показывает, что printf-ы на некоторых системах тормозят сильнее, чем файловый ввод-вывод. Я даже с тобой согласился, хотя аналогичный код на моём рабочем компе изредка работает дольше там, где должен в теории работать быстрее. Я не качаю торренты на работе, хотя винт может быть фрагментирован, т.к. он у меня там один.
И почему в таком случае моё утверждение является голословным? Напомню, о чём идёт речь:
Если в твоей программе конвертация чисел в строки является критичным по скорости местом, то скорее всего ты дурилка и она им не является.
А типа экспорт чего-то числового в большой xml?
Там ботлнеком будет запись в файл, а не преобразование чисел.

kokoc88

И не важно что он будет дольше компилироваться и выполняться.
Библиотеки boost никогда не были предназначены для скорости. И если их нельзя использовать в каких-то очень редких и исключительных случаях, то это не значит, что в остальных случаях, когда требуется стабильность работы и скорость разработки, их использовать ни в коем случае нельзя.

tamusyav

А я использу snprintf/strftime/..., и для парсинга те же аналоги, у меня всё всегда работает
До тех пор, пока ты не столкнешься с ситуацией, когда у тебя будет вылезать не пойми что, а компилятор и даже сама программа во время исполнения будут молчать о том, что у тебя бардак с типами в snprintf.
Пишу тоже быстро, что я желаю не так?
Сопровождать свой код ты, по-видимому, не желаешь.

Werdna

компилятор и даже сама программа во время исполнения будут молчать о том, что у тебя бардак с типами в snprintf.
Компилятор вообще-то кидает ворнинги.
Сопровождать свой код ты, по-видимому, не желаешь.

они просто работают.

evolet



bash3.2$ cat a.c
#include <stdio.h>

int main(void)
{
int i;
for (i = 0; i < 10000000; i++)
printf("%d\n", i+10000000);
fsync(1);
return 0;
}

bash3.2$ cat b.c
#include <stdio.h>

const char *s = "10000001\n";
int l = 9;

int main(void)
{
int i;
for (i = 0; i < 10000000; i++)
fwrite(s, sizeof(char l, stdout);
fsync(1);
return 0;
}

bash3.2$ time ./a > aa

real 0m6.453s
user 0m2.962s
sys 0m0.286s
bash3.2$ time ./b > bb

real 0m4.331s
user 0m0.637s
sys 0m0.258s

как видишь, если если считать не до момента "отдали данные ОС, пусть она их когда-нибудь запишет на диск", то разница получается уже гораздо меньше

evolet

кста, твой тест совсем плох, ибо не сравнивает даже скорость "форматирования" с сисколами.

x:~/temp$ cat b.c
#include <stdio.h>

int main(void)
{
int i;
char s[] = "10000001\n";
for (i = 0; i < 10; i++) {
fwrite(s, 1, 9, stdout);
}
return 0;
}

x:~/temp$ strace ./b > bb
execve("./b", ["./b"], [/* 36 vars */]) = 0
brk(0) = 0x8484000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
........................................................
munmap(0xb782a000, 70372) = 0
fstat64(1, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb783b000
write(1, "10000001\n10000001\n10000001\n10000"..., 90) = 90
exit_group(0) = ?

тут на 10 fwrite пришелся один write

salamander

Да, справедливое исправление. Перемерил с ним (размер поставил 1Гб):
на моем ноутбуке
printf:
real    0m37.176s
user 0m22.453s
sys 0m2.164s

fwrite:
real    0m33.253s
user 0m4.220s
sys 0m2.191s

на melchior.msu
printf:
real    0m19.913s
user 0m16.233s
sys 0m2.300s

fwrite:
real    0m15.669s
user 0m3.184s
sys 0m2.352s

User time у printf сильно больше, чем у fwrite (более чем в 5 раз Real time на 10-25% всего. Что вобщем-то логично: запись на диск идет параллельно с вычислениями. То есть в этих примерах fprintf работает примерно столько же, сколько и запись.
В любом случае, говорить что запись на хард является ботлнеком и от скорости форматирования ничего не зависит нельзя.

salamander

кста, твой тест совсем плох, ибо не сравнивает даже скорость "форматирования" с сисколами.
А он их и не пытается сравнивать. Вопрос-то был в том, действительно ли скорость записи харда на столько меньше скорости форматирования чисел, что последнее на время выполнения программы не влияет. И где тратится время при форматировании: в сисколлах или циклах самой программы не суть важно. Тем более, system time при измерениях у fwrite и fprintf отличается очень слабо.

Dasar

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

salamander

Нифига не очевидное утверждение. Запись на хард идет параллельно с работой процессора. Таким образом твой "пищущий" поток будет заниматься только перекладыванием данных из одного буфера в другой. Главное что форматирующий поток он от этой работы не избавит: тому придется перекладывать данные из своего буфера в буфер "пищущего" потока. Плюс ты разживешься затратами на синхронизацию этих двух потоков. Короче, пример в студию. Будем мерить.

ava3443

Зато он совершенно небезопасен с точки зрения типизации
GCC и свежие компиляторы на UNIXах (HP aCC на HPUX/IA64, IBM xlC на AIX, с другими не работал) диагностируют ошибки несоответствия форматной строки и передаваемых аргументов.
А Микрософту должно быть стыдно за то, что они до сих пор этого не сделали (поправьте если ошибаюсь; 2010 не пробовал, а 2008 вроде как не диагностирует)

asvsergey

 
А я использу snprintf/strftime/..., и для парсинга те же аналоги, у меня всё всегда работает. Пишу тоже быстро, что я желаю не так?

Возможно тебе не надо писать/читать данные в/из xml, используя сторонний парсер, которому на вход нужны std::string.

kokoc88

Вопрос-то был в том, действительно ли скорость записи харда на столько меньше скорости форматирования чисел, что последнее на время выполнения программы не влияет.
Конечно же она меньше, почему это до сих пор вызывает у тебя вопросы? :) Если printf/iostreams слишком сильно тормозят, то сравни с itoa (и далее со своей функцией преобразования, чтобы ещё быстрее работала).

Werdna

Возможно тебе не надо писать/читать данные в/из xml, используя сторонний парсер, которому на вход нужны std::string.
Для чтения я использую свою маленькую библиотечку txml (обертка над expat на плюсах).
Для генерации xml я использую шаблонизатор ctpp2.
И ещё я стараюсь не использовать xml. Это весьма своеобразный формат, далеко не всегда он хорош.

kokoc88

GCC и свежие компиляторы на UNIXах (HP aCC на HPUX/IA64, IBM xlC на AIX, с другими не работал) диагностируют ошибки несоответствия форматной строки и передаваемых аргументов.
Это относится только к строкам, передаваемым непосредственно в printf, или в следующем случае тоже будет варнинг?
void printf_my_params(const char* format, int param1, const char* param2)
{
printf(format, param1, param2);
}

salamander

Конечно же она меньше, почему это до сих пор вызывает у тебя вопросы?
А почему у меня их не должно быть? Эксперимент вон показывает, что они примерно равны, и, соответственно, оба торомозят программу.
Если printf/iostreams слишком сильно тормозят, то сравни с itoa (и далее со своей функцией преобразования, чтобы ещё быстрее работала).
Пример в студию. Мне пока не удалось самописными функциями добиться заявляемого тобой и результата: чтобы программа работала столько же, сколько и один вывод.
PS: itoa не входит в стандарт языка C.

vall

трэд не читал, но скажу:
а printf по '\n' буффера не сбрасывает?

procenkotanya

Да, по дефолту stdout должен буферизоваться построчно, а stderr посимвольно.

kokoc88

А почему у меня их не должно быть? Эксперимент вон показывает, что они примерно равны, и, соответственно, оба торомозят программу.
По поводу чистоты эксперимента я уже несколько раз высказывался выше. Не вижу смысла дальше об этом спорить.
Мне пока не удалось самописными функциями добиться заявляемого тобой и результата: чтобы программа работала столько же, сколько и один вывод.
Очень странно. У Microsoft получается, а у тебя нет? Ну посмотри исходники функции _itoa, кстати она там весьма неэффективно реализована.
Пример в студию.
Давай сделаем другой пример, чтобы исключить различные факторы. (Например, запись одних и тех же данных из одного и того же адреса в памяти может происходить немного быстрее.) Померяем чистое время различных функций отдельно:
 
	FILE* f = ::fopen("test1.txt", "w");
DWORD start = ::GetTickCount;
for (int i = 0; i < 100000000; i++)
::fwrite("10000001\n", sizeof(char 9, f);
::fclose(f);
::printf("time: %f\n", (::GetTickCount-start)/1000.0);

char buf[16];
start = ::GetTickCount;
for (int i = 0; i < 100000000; i++)
::_itoa(10000000 + i%10000000, buf, 10);
::printf("time: %f\n", (::GetTickCount-start)/1000.0);

start = ::GetTickCount;
for (int i = 0; i < 100000000; i++)
::sprintf(buf, "%d", 10000000 + i%10000000);
::printf("time: %f\n", (::GetTickCount-start)/1000.0);
У меня получается такой результат:
time: 20.187000
time: 6.188000
time: 29.781000

salamander

хз, но fsync сильно повлиял на результаты.

vall

не путай fsync и fflush. я говорю про лузерспейсную буферизацию в stdio

salamander

Давай сделаем другой пример
Вот давно бы так, вместо того, чтобы рассуждать на тему, что у меня наверное пример неправильный.
чтобы исключить различные факторы. (Например, запись одних и тех же данных из одного и того же адреса в памяти может происходить немного быстрее.) Померяем чистое время различных функций отдельно
Ну, все факторы ты не исключишь.
У меня получается такой результат
Да, у меня результаты сходные.
time: 14.719000
time: 4.844000
time: 23.968000

Осталось допилить вывод с помощью _atoi, чтобы он работал примерно за столько же, сколько и просто fwrite. Если предположение о параллельной работе харда и процессора верно, то это должно быть вполне возможно. Однако
	f = ::fopen("test2.txt", "w");
start = ::GetTickCount;
for (int i = 0; i < 100000000; i++) {
::_itoa(10000000 + i%10000000, buf, 10);
buf[8] = '\n'; buf[9] = '\0';
::fwrite(buf, sizeof(char 9, f);
}
::fclose(f);
::printf("time: %f\n", (::GetTickCount-start)/1000.0);

дает результат
time: 19.063000
что равно сумме времени работы fwrite + _atoi. Так что либо запись на хард идет не параллельно с вычислениями (как-то слабо верится либо тут еще в чем-то затык. У кого нибудь есть какие-нибудь соображения на этот счет?
PS: где смотреть исходники _itoa? Go to definition/declaration кидают меня в stdio.h (не удивительно, вобщем-то).

ava3443

Это относится только к строкам, передаваемым непосредственно в printf, или в следующем случае тоже будет варнинг?
void printf_my_params(const char* format, int param1, const char* param2)
{
printf(format, param1, param2);
}
Конечно, я подразумевал что форматная строка должна быть видна компилятору, иначе это уже в runtime нужно проверять, разве нет?
Я считаю что если приведенный выше пример - в пользовательском коде, то нужно что-нибудь отстреливать автору. Если же это действительно нужно, например в какой-нибудь своей библиотеке для логгирования :) , то придётся в рантайме ошибки ловить - всякие unhandled exception фильтры...

ava3443

PS: где смотреть исходники _itoa? Go to definition/declaration кидают меня в stdio.h (не удивительно, вобщем-то).
При установке visual студии можно указать чтобы поставились исходники CRT-библиотеки. Если они установлены, то для 2003-ей студии например исходный код itoa здесь: ...\Microsoft Visual Studio .NET 2003\Vc7\crt\src\xtoa.c. В 2008-ой аналогично (Microsoft Visual Studio 9.0\VC\crt\src\xtoa.c)
P.S. вот ещё на заметку: http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

Werdna

void printf_my_params(const char* format, int param1, const char* param2) { printf(format, param1, param2); }
А зачем так писать?

Serab

Ну прямо так, конечно, незачем. Но вот, допустим, есть у нас своя собственная библиотечка с нашими собственными классами для строчек. И хотим мы в ней аналог sprintf, только работающий исключительно на наших строчках. Вот затем и надо.
Странно только то, что это не очевидно тебе.

Werdna

Ну прямо так, конечно, незачем. Но вот, допустим, есть у нас своя собственная библиотечка с нашими собственными классами для строчек. И хотим мы в ней аналог sprintf, только работающий исключительно на наших строчках. Вот затем и надо.
Странно только то, что это не очевидно тебе.
Мне вот не странно что я такого не хочу.
Аналог snprintf для своих каких-то строк? Я в декларации функции пропишу формат, и компилятор точно так же булет кидать ворнинги.

Serab

Мне вот не странно что я такого не хочу.
ну а как ты совмещаешь оо-строки и свой любимый sprintf?

Serab

Аналог snprintf для своих каких-то строк? Я в декларации функции пропишу формат, и компилятор точно так же булет кидать ворнинги.
Вот, это уже другой разговор, тоже хотел посмотреть, есть ли там возможность для своих функций так делать. Ну раз есть, то вообще круто.

Werdna

Что такое оо-строки? std::string?
Я пишу так:
std::string s;
...
char buf[1024];
snprintf(buf, 1024, ФОРМАТ, ДАННЫЕ);
s = buf;

Serab

Что такое оо-строки? std::string?
Как вариант.
Я пишу так:
std::string s;
...
char buf[1024];
snprintf(buf, 1024, ФОРМАТ, ДАННЫЕ);
s = buf;
Ужас, выбросим повторное использование кода на помойку. Больше дублирования, хорошего и разного. Больше магических констант, осмысленных, но беспощадных.

Serab

Ну и еще для любителей микрооптимизаций всяких: вот у тебя лишнее копирование, временный буфер на стеке, как к этому оптимизатор относится, неизвестно.

Werdna

Больше магических констант, осмысленных, но беспощадных.
А тебе разве не говорили, что на плюсах ты сам контролируешь ресурсы? Ну да, это не ПХП, но прикинуть по максимуму длинну строки не так уж сложно.
Ужас, выбросим повторное использование кода на помойку.

Да, я стараюсь не заморачиваться на тему повторного использования кода. Мне важно чтобы работало в одном проекте, а повторно использовать, плодя "классики" — явно не мой метод.
Больше дублирования, хорошего и разного.

Это вообще про что?

Werdna

Ну и еще для любителей микрооптимизаций всяких: вот у тебя лишнее копирование, временный буфер на стеке, как к этому оптимизатор относится, неизвестно.
Поэтому чаще всего буфер уже где-то в другом месте (не на стеке или отправляется в какой-то вызов далее без копирования.
Код был ответом на твой вопрос как получить std::string. Если так надо повторное использование кода, напиши inline-функцию. Будет тебе в одну строчку.

kokoc88

А зачем так писать?
Даже странно, что у тебя возникает этот вопрос. Причин может быть масса. Логирование, синхронизация вывода из нескольких потоков, настраиваемый формат вывода (в зависимости от каких-то условий ты и сам можешь придумать примеры, где это потребуется. Конечно, в каких-то случаях ты мог бы нагенерировать копипасты, но тогда твой код очень быстро станет похож на помойку.
Кроме того, ты же сам часто пишешь в этом разделе "пишите сразу кроссплатформенно", что подразумевает в том числе поддержку разных компиляторов, в том числе и тех, которые не выдают варнингов.

Serab

А тебе разве не говорили, что на плюсах ты сам контролируешь ресурсы? Ну да, это не ПХП, но прикинуть по максимуму длинну строки не так уж сложно.
забрось-ка свой менторский тон куда подальше, мне мало чего говорили, я в основном читал, по сути отвечу ниже.
Больше дублирования, хорошего и разного.
Это вообще про что?
Да то, что руки опухнут каждый раз четыре строки писать. А если у меня функция принимает два строковых параметра и каждый из них надо форматнуть. Ну и еще в твоем коде проверки на ошибку нету, он будет подло обрезать лишние символы и молчать.
Никто не запрещает написать код, который будет делать несколько попыток подобрать размер буфера, например, удваивая его, но копипастить эти блоки стопицот раз — увольте.

Werdna

Ну и еще в твоем коде проверки на ошибку нету, он будет подло обрезать лишние символы и молчать.
Если я знаю формат и максимальные длины аргументов, ничего потеряно не будет.
Если данные не ограничены по длинне, то можно выделить буфер сильно больше. Обычно это не надо.
копипастить эти блоки стопицот раз — увольте.

напиши удобный в твоем конкретно случае враппер над этой простой операцией.

Serab

напиши удобный в твоем конкретно случае враппер над этой простой операцией.
ну так и сделано :) про это и говорим. Ты чего?

yroslavasako

Померяем чистое время различных функций отдельно:
А что gettickcount меряет чистое процессорное время процесса? А не просто время окружающей среды? API успело измениться с тех пор, как я последний раз с ним работал?

kokoc88

А что gettickcount меряет чистое процессорное время процесса? А не просто время окружающей среды? API успело измениться с тех пор, как я последний раз с ним работал?
Не надо троллить, в этой задаче не требовалась точность, о которой ты пишешь.

xronik111

Google по gcc attribute format printf.

erotic

Да, я стараюсь не заморачиваться на тему повторного использования кода. Мне важно чтобы работало в одном проекте, а повторно использовать, плодя "классики" — явно не мой метод.
Это, к сожалению, заметно. Поэтому когда одну инкарнацию этого кода поправишь, потом неизменно найдешь еще пару его копий, которые, конечно, не поправлены.
А txml меня не впечатляет тем, что время его работы растет, наверное, квадратично от размера xml. Потому как на каждый распознанный токен вызывается determineMember, а в каждом determineMember на каждый параметр в xml вызывается N determine.

Werdna

А txml меня не впечатляет тем, что время его работы растет, наверное, квадратично от размера xml. Потому как на каждый распознанный токен вызывается determineMember, а в каждом determineMember на каждый параметр в xml вызывается N determine.
txml медленный, но на нём удобно писать конфиги.
Вообще, не надо хотеть скростить xml и скорость. Везде, где есть xml, будут тормоза. Поэтому если что-то тормозит, меняй формат.
Есть форматы быстрые, а есть универсально удобные. XML не из первой группы.
Это, к сожалению, заметно. Поэтому когда одну инкарнацию этого кода поправишь, потом неизменно найдешь еще пару его копий, которые, конечно, не поправлены.

Во-первых, если штуки совсем одинаковые, то такое дублирование — банальная лень объединить.
Но ещё бывает так, что лучше разделить что-то на два разных куска, чем дорабатывая одно потом ломать другое.

erotic

txml медленный, но на нём удобно писать конфиги.
Ладно бы конфиги, к ним претензий по производительности не предъявишь. Но он же у вас не только для конфигов используется ;)
Оставить комментарий
Имя или ник:
Комментарий: