C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Скажите, это нормальный while?
Benish
Отправлено: 14.01.2005, 15:14


Дежурный стрелочник

Группа: Участник
Сообщений: 67



Подскажите пожалуйста!

Пишу:

CODE

while (Position_end != (Position_find = find(Pos_begin,Pos_end,MARKER)))
{
//.......
}



Выглядит очень по уродски.
Но суть в том, что результат ф-ции find нужен будет в вычислениях внутри while.
м.б. использовать что-то типа:

CODE

Position_find = find(Pos_begin,Pos_end,MARKER);

while (Position_end != Position_find)
{
//........
Position_find = find(Pos_begin,Pos_end,MARKER);
}




Вроде уже лучше, но тоже как-то странно.....
Sl@Sh
Отправлено: 14.01.2005, 15:18


Мастер участка

Группа: Участник
Сообщений: 383



Пожалуйста опишите подробней — какова задача цикла и функции.
Guest
Отправлено: 14.01.2005, 15:34


Не зарегистрирован







Чисто формально можно сделать так

for(Position_find = find(Pos_begin,Pos_end,MARKER); Position_end != Position_find; Position_find = find(Pos_begin,Pos_end,MARKER)wink.gif
{ ...
}

ни чего не поменялось, но выглядит красивее
full_lamer
Отправлено: 14.01.2005, 15:39


Машинист паровоза

Группа: Участник
Сообщений: 225



QUOTE (Guest @ 14/01/2005, 16:36)
Чисто формально можно сделать так
for(Position_find = find(Pos_begin,Pos_end,MARKER); Position_end != Position_find; Position_find = find(Pos_begin,Pos_end,MARKER)wink.gif
{ ...
}

а производетельность — какая разница как выглядит — главное чтобы работало быстро и правильно — а на крайний случай можно комментариями засеять... я считаю что первый вариант выглядит куда привлекательней, предложенный автором темы....
опять же ИМХО...
Guest
Отправлено: 14.01.2005, 16:18


Не зарегистрирован







2full_lamer посмотрите внимательно и подумайте. Это только способ записи. Число и опрядок операций в цикле for и первом while идентично.
full_lamer
Отправлено: 14.01.2005, 16:41


Машинист паровоза

Группа: Участник
Сообщений: 225



2Guest
полностью согласен — но цитирую "если результат один — зачем платить больше?" while приятней читать... хотя у for больше возможностей...

а кстати кто знает как откомпилирует эти два цикла компилятор Builder'а?
Guest
Отправлено: 14.01.2005, 16:45


Не зарегистрирован







Хм, интересно.
ИМХО, так красивее. Только, насколько я понимаю, маленькое исправление (в конце не Pos_begin, а Pos_find):

CODE

for(Position_find = find(Pos_begin,Pos_end,MARKER); Position_end != Position_find; Position_find = find(Pos_find,Pos_end,MARKER)
{ ...
}



Спасибо.
Вообщем как я понимаю и мой while был нормальный. А то я уж испугался wink.gif wink.gif wink.gif
Георгий
Отправлено: 14.01.2005, 18:43


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



QUOTE (full_lamer @ 14/01/2005, 17:43)
а кстати кто знает как откомпилирует эти два цикла компилятор Builder'а?

одинаково хреново — тут оптимизировать нечего т.к. вызов функции займёт в разы больше времени чем накладные расходы на организацию цикла.

а если вопрос об оптимизации цикла сообще то for лучше оптимизиреутся, потому как правило о нём известно больше — в частности в явном виде описана инициализация цикла и действие выполняемое по завершении каждой итерации. и можно переменные используемые в цикле перенести в регистры, вынести из цикла код инициализации (чтоб конвеер и предсказание ветвлений не пугать)

а если цикл примитивный, например:
CODE
while(*(p++)=(*q++));
то тут while быстрее for`а, но всёравно медленнее, чем такоеже действие, но выполненное бибиотечной функцией — в данном случае strcpy

только что заметил, что скобки не так стоят:
CODE
while(*(p++)=*(q++));


Отредактировано Георгий — 19/01/2005, 22:22
Benish
Отправлено: 19.01.2005, 14:39


Дежурный стрелочник

Группа: Участник
Сообщений: 67



При компиляции следующей программы:

CODE


   int i,a;
   a=i=0;

   for (;i++<10;)
     {
       a++;
       Memo1->Lines->Add(a);
     }

   a=i=0;

   while (i++<10)
     {
       a++;
       Memo1->Lines->Add(a);
     }



Код генерируется абсолютно одинаковый.
Если сделать "честный" for (for(i=0;i<10;i++), то for будет меньше while на 1 jump.
Все это можно увидеть в отладчик СВС установив точку останова.
Guest
Отправлено: 19.01.2005, 15:52


Не зарегистрирован







Небольшое дополнение и ассемблерный код можно смотреть прямо в окне стройки
CODE

int i,a;
  a=i=0;

  for (;i++<10;)
    {
      a++;
      Memo1->Lines->Add(a);
    }

  a=i=0;

  while (i++<10)
    {
      a++;
      Memo1->Lines->Add(a);
    }

asm {qwe};
Benish
Отправлено: 19.01.2005, 15:57


Дежурный стрелочник

Группа: Участник
Сообщений: 67



Далее.
При выполнении программы:

CODE

   char str1[13],str2[13];
   char *pstr1,*pstr2;
   strcpy(str1,"This is test");
   pstr1=str1;
   pstr2=str2;

// фрагмент1
   while((*pstr2++) = (*pstr1++));
// фрагмент1

   strcpy(str2,"");    

// фрагмент 2
   strcpy(str2,str1);
// фрагмент 2



Фрагмент1 выполнялся 2,93 миллисек, а Фрагмент2 669,93 микросек.
Т.е 0,00293 сек и 0,0066993 сек. соответственно.

Можно сказать, что библиотечное копирование почти в 3 раза дольше.

Про генерацию одинакового кода для:

for (; ((*pstr2++) = (*pstr1++)); )

и

while((*pstr2++) = (*pstr1++));

я уже говорил.
Guest
Отправлено: 19.01.2005, 16:14


Не зарегистрирован







Непонял. 669,93 микросек это ведь 0,66993 миллисек или 0.00066993 сек
Benish
Отправлено: 19.01.2005, 16:27


Дежурный стрелочник

Группа: Участник
Сообщений: 67



Ну вот, блин, как всегда sad.gif
Опять сенсации не получилось sad.gif

Георгий
Отправлено: 19.01.2005, 21:24


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



всё таки библиотечный strcpy более чем в 4 рза быстрее самоделки?

кстати тест нескольно не корректный — при работе "фрагмент 1" данные наврядли находятся в кэш памяти, а при работе "фрагмент 2" они наверняка в кэш`е уже оказались (в результате отработки "фрагмент1").
Benish
Отправлено: 20.01.2005, 15:51


Дежурный стрелочник

Группа: Участник
Сообщений: 67



QUOTE (Guest @ 19/01/2005, 16:54)
Небольшое дополнение и ассемблерный код можно смотреть прямо в окне стройки
CODE

.....skip....

asm {qwe};



И что измениться, если сие вписать в программу?
У меня Билдер ругаться начинает что expression syntax!
Benish
Отправлено: 20.01.2005, 15:52


Дежурный стрелочник

Группа: Участник
Сообщений: 67



Вопрос!

А можно ли как-нибудь извлекать информацию из отладчика Builder'a?
Ну типа в файл скопировать.
Benish
Отправлено: 20.01.2005, 15:58


Дежурный стрелочник

Группа: Участник
Сообщений: 67



Провел эксперимент еще раз. Он принес ожидаемый результат.
Была использована программа:

CODE

   char str1[13],str2[13];
   char *pstr1,*pstr2;
   pstr1=str1;
   pstr2=str2;
   strcpy(str1,"This is test");
   strcpy(str2,"            ");
фрагмент1
   while((*pstr2++) = (*pstr1++));
фрагмент1
   strcpy(str1,"This is test");
   strcpy(str2,"            ");
фрагмент2
   strcpy(str2,str1);
фрагмент2



Результат получился вполне предсказуемый:

Фрагмент1 — 1.14 milli sec
Фрагмент2 — 1.13 milli sec

Р4-1,6 GHz однако.
Георгий
Отправлено: 20.01.2005, 16:42


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



~1 милисекунд на копирование 13 байт? т.е. 100 нан на байт т.е. ~500 тактов на байт?? многовато.
сейчас сам померю.

значит так — на процессоре p3m 650MHz получены следующие результаты:
строка длиною в 100 символов
1. копирование циклом while ~770 тактов = ~8 тактов на байт
2. копирование strcpy ~320 тактов = ~3 такта на байт
3. копирование memcpy ~95 тактов = ~1 такта на байт

строка длиною в 10 символов
1. ~110 тактов = 10 тактов на байт
2. ~35 тактов = 3 такта на байт
3. ~40 тактов = 4 такта на байт

всё таки библиотечная быстрее, чуть ли не в 3 раза

Отредактировано Георгий — 20/01/2005, 20:19
Benish
Отправлено: 21.01.2005, 14:34


Дежурный стрелочник

Группа: Участник
Сообщений: 67



Скажите пожалуйста, а как проводились измерения?
Guest
Отправлено: 21.01.2005, 15:05


Не зарегистрирован







QUOTE
И что измениться, если сие вписать в программу?
У меня Билдер ругаться начинает что expression syntax!

Ругаться — это само собой, но у меня в соседнем окне показывается ассемблерный код, спозиционированный на эту строку. Удобно.

Вернуться в Вопросы программирования в C++Builder