Re[27]: Об эффективности программ
От: Pavel Dvorkin Россия  
Дата: 21.10.05 05:44
Оценка: :)
Здравствуйте, Дарней, Вы писали:


Д>небольшой эксперимент показал, что лишенный проблем с безопасностью вариант с использованием std::string еще и работает куда быстрее, чем твой вариант — ценой потери небольшого количества памяти из тех гигабайтов, которые были у тебя в наличии, но которые ты не использовал

Д>Вот мне и стало интересно — чего ты в конце концов хотел добиться своими "оптимизациями"?

Ты бы хоть внимательно посмотрел, что ты со string сделал

std::string firstName = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
std::string lastName = "22222222222222222222222222222222222222222222222222222222222222222222222222222";
std::string astr = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
std::string bstr = "11111111111111111111111111111111111111111111111111111111111111111111111111111";

Это, между прочим, вызов конструктора. Который при этом вычисляет длину (поле string::_MySize) и теперь эта длина используется в операциях = и +=. А вызываешь этот конструктор ты один раз, а не 10000000 раз. Вот поставь так

        std::string res;
        for(size_t i=0;i<10000000;++i)
        {
        std::string firstName = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
        std::string lastName = "22222222222222222222222222222222222222222222222222222222222222222222222222222";
        std::string astr = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
        std::string bstr = "11111111111111111111111111111111111111111111111111111111111111111111111111111";

            res = firstName;
            res += lastName;
            res += astr;
            res += bstr;
        }


тогда и сравнивай.
Конечно, в этом случае и в моем коде надо сделать то же


char szTotal[500];
char * pszTmpTotal,*pszTmpFirst, *pszTmpLast;
for(size_t i=0;i<10000000;++i)
{
   char* szFirstName = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
   char* szLastName =  "22222222222222222222222222222222222222222222222222222222222222222222222222222";
   char* astr = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
   char* bstr = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
   for(pszTmpTotal = szTotal,pszTmpFirst = szFirstName ; *pszTmpFirst;*pszTmpTotal++=*pszTmpFirst++); 
   for(pszTmpLast = szLastName; *pszTmpLast;*pszTmpTotal++=*pszTmpLast++); 
   for(pszTmpLast = astr; *pszTmpLast;*pszTmpTotal++=*pszTmpLast++); 
   for(pszTmpLast = bstr; *pszTmpLast;*pszTmpTotal++=*pszTmpLast++); 
   *pszTmpTotal = '\0';
}


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

P.S. А вообще-то я придумал способ сделать еще быстрее. Примерно в 2 раза быстрее, чем мой вариант. Жаль, что в свое время до него не додумался.
Причем даже с нахождением длины, т.е. двухпроходный. Так что одна причина, почему я позволил себе потенциально небезопасный код, отпадает.. Вот только буфер все же придется оставить статическим — при попытке вставить в цикл выделение памяти и освобождение он проигрывает даже string. Так что полностью безопасным сделать все равно не удастся. Ну а кроме того, в реальной программе этот буфер жил очень долго, и строки в него добавлялись по мере надобности. И не только строки
With best regards
Pavel Dvorkin
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.