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)
{ ...
}
ни чего не поменялось, но выглядит красивее |
|
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)
{ ...
} |
а производетельность — какая разница как выглядит — главное чтобы работало быстро и правильно — а на крайний случай можно комментариями засеять... я считаю что первый вариант выглядит куда привлекательней, предложенный автором темы....
опять же ИМХО...
|
|
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 был нормальный. А то я уж испугался |
|
Георгий |
Отправлено: 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
|
Ну вот, блин, как всегда
Опять сенсации не получилось
|
|
Георгий |
Отправлено: 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!
|
Ругаться — это само собой, но у меня в соседнем окне показывается ассемблерный код, спозиционированный на эту строку. Удобно. |
|