· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ZEN —› Запутался в loop'ах :(((

<< . 1 . 2 . 3 . >>

Посл.отвђт Сообщенiе


Дата: Июн 10, 2004 22:02:29

Где же это просто счётчик?
Ты ж его как индекс используешь.
Вот для работы с индексами от старшего до 0 оба включетельно:
for (int i=старший индекс;i>=0;i--)
{
   if (u_ptr[bait].hash == bobject[i].hash)
    {
     bait_index = i;
     break;
    }
}


Дата: Июн 10, 2004 22:05:43

Ну да. Индекс. Как счетчик :)
Свин, ваш цикл мне не нравится, do/while оптимальнее. Я бы вообще перешел на поинтерную арифметику, но индекс связывает два массива разнородной структуры и так проще. Можно, конечно, работать с двумя поинтерами сразу, но ... Да пошло оно... Все равно никто не оценит и денег больше не заплатят.


Дата: Июн 10, 2004 22:13:24

Может так будет быстрее?
hash = u_ptr[bait].hash;
i=lastindex;
p=bobject+i; //если конечно это массив

metka:
   if (hash != p->hash)
   {
      p--;
      if(i--)
        goto metka;
   }
   else
     bait_index = i;


Дата: Июн 10, 2004 22:28:19

Black_mirror

М-а-ать! Я баран! Блин, такого не увидеть. Слепой крот, осел, дурундук... Умница! Подметил! Вынос константы за пределы цикла. Позор на мою лысину, а-а-а-а
:((((((((((((((((((((((((((((((((((((((((((((((((((((

Что до самого представления цикла - да, работать будет гораздо быстрее, но гораздо сложнее для понимания. С другой стороны - можно поставить комментарий... :)


Дата: Июн 10, 2004 22:29:11

но индекс связывает два массива разнородной структуры

Ни хрена он не связывает, а я осел! :(


Дата: Июн 10, 2004 22:40:19

Black_mirror

Слушай, а давай ты мне еще вот это вот соптимизируешь. :)))

static void PrintMATRIX(bindob *bobject, Int4 el_num, Int4 mcid)
{
	char buff[BUF_LEN*4];
	Int4 i = 0, j = 0;
 
	while(i < el_num - 1)
	/*we skip the very last element - it cannot be printed with itself*/
	{
			sprintf(buff, "%u\t%s\t%s\t%s\t%u\t%u", 
					mcid, bobject[i].mol_type, bobject[i].mol_db, bobject[i].mol_acc, 
					bobject[i].mol_gi, bobject[i].mol_tax);
			j = i + 1;
								
			while(j < el_num)
			{
				fprintf(g_openfiles.matrix, "%s\t%s\t%s\t%s\t%u\t%u\n", 
						buff, bobject[j].mol_type, bobject[j].mol_db, 
						bobject[j].mol_acc, bobject[j].mol_gi, bobject[j].mol_tax);
				j++;
			}
		i++;
	}
}


Дата: Июн 10, 2004 22:59:36

Свин, ваш цикл мне не нравится, do/while оптимальнее
Докажи.


Дата: Июн 10, 2004 23:15:49

The Svin

Доказываю.
Постулаты:
1) Программа компилируется в дебажном(!) режиме, т.к. в релизе VC-компилятор раскрутит оба цикла, что сделает сравнение бессмысленным.

Сишный код:
void main()
{
	int i = 9;
	char arr[10];
	
	for(; i>0; i--)
	{
		arr[i] = i;
		printf("%u\n", arr[i]);
	}

	i = 9;
	do
	{
		arr[i] = i;
		printf("%u\n", arr[i]);
	}while(--i);

}


Ассемблерный код:
.text:00411A57 _for_loop:                              ; CODE XREF: main+56j
.text:00411A57                 mov     eax, [ebp+int_i]
.text:00411A5A                 sub     eax, 1
.text:00411A5D                 mov     [ebp+int_i], eax
.text:00411A60
.text:00411A60 break:                                  ; CODE XREF: main+25j
.text:00411A60                 cmp     [ebp+int_i], 0
.text:00411A64                 jle     short loc_411A88
.text:00411A66                 mov     eax, [ebp+int_i]
.text:00411A69                 mov     cl, byte ptr [ebp+int_i]
.text:00411A6C                 mov     [ebp+eax+char_arr], cl
.text:00411A70                 mov     eax, [ebp+int_i]
.text:00411A73                 movsx   ecx, [ebp+eax+char_arr]
.text:00411A78                 push    ecx
.text:00411A79                 push    offset aU       ; "%u\n"
.text:00411A7E                 call    printf
.text:00411A83                 add     esp, 8
.text:00411A86                 jmp     short _for_loop
.text:00411A88 ; ---------------------------------------------------------------------- -----
.text:00411A88
.text:00411A88 loc_411A88:                             ; CODE XREF: main+34j
.text:00411A88                 mov     [ebp+int_i], 9
.text:00411A8F
.text:00411A8F do_while:                               ; CODE XREF: main+88j
.text:00411A8F                 mov     eax, [ebp+int_i]
.text:00411A92                 mov     cl, byte ptr [ebp+int_i]
.text:00411A95                 mov     [ebp+eax+char_arr], cl
.text:00411A99                 mov     eax, [ebp+int_i]
.text:00411A9C                 movsx   ecx, [ebp+eax+char_arr]
.text:00411AA1                 push    ecx
.text:00411AA2                 push    offset aU       ; "%u\n"
.text:00411AA7                 call    printf
.text:00411AAC                 add     esp, 8
.text:00411AAF                 mov     eax, [ebp+int_i]
.text:00411AB2                 sub     eax, 1
.text:00411AB5                 mov     [ebp+int_i], eax
.text:00411AB8                 jnz     short do_while


Дата: Июн 10, 2004 23:17:06 · Поправил: volodya

В обоих случаях видно как действует на цикл постусловие и предусловие. См на:
mov     eax, [ebp+int_i]
sub     eax, 1
mov     [ebp+int_i], eax


и на
cmp     [ebp+int_i], 0
jle     short loc_411A88


Дата: Июн 10, 2004 23:26:34

volodya
Слушай, а давай ты мне еще вот это вот соптимизируешь. :)))
Хотелось бы знать на сколько длинные строки, и какого порядка значение el_num.


Дата: Июн 10, 2004 23:29:41

Black_mirror

:)
Да не трать свое время на фигню всякую :) Спасибо и так! Хороший пример! И наблюдательность хорошая. И голова!

BUF_LEN определен как 100. Т.е. 400 символов.
el_num, варьирует, скажем, от 1 до 80.


Дата: Июн 10, 2004 23:48:47

volodya
Ну ты хоть скажи, стали ли откомпилированные программы лучше после этих оптимизаций. Всё, о чём сейчас шла речь, было известно, и реализовано в автоматических оптимизаторах ещё в 70-х годах 20 века...


Дата: Июн 11, 2004 00:01:09 · Поправил: Black_mirror

volodya
printf штука тормозная, поэтому сами циклы оптимизировать смысла нет, но возможно стоит сделать так:
static char buf[el_num_max][BUF_LEN*4];//массив лучше сделать
// статическим, так как new штука тормозная

bindob *bo=bobject;
for(int i=0;i<el_num;i++)
{
  sprintf(buf,"\t%s\t%s\t%s\t%u\t%u",
      bo->mol_type, bo->mol_db, bo->mol_acc, 
      bo->mol_gi, bo->mol_tax);
  bo++;
}
for(i=0;i<el_num-1;i++)
   for(int j=i+1;j<el_num;j++)
      fprintf(g_openfiles.matrix,"%u%s%s",buf[i],buf[j]);


Дата: Июн 11, 2004 00:01:22

А можно подумать я тут велосипед изобретаю. Я прекрасно понимаю, что эти проблемы были разрешены и все такое прочее. Но ответь на другой вопрос. А сколько проблем в комплексе может решить компилятор? Скажем, я сталкивался с проблемой в VC 7.0! Знаешь же, что если заменить индекс на поинтерную арифметику получим явный прирост. Казалось бы, трюк известен всем. Так вот, после того как скомпилировали пример в режиме максимальной оптимизациями со всеми опциями до которых я мог дотянуться мышью, индексы так и не были убраны! Переписали - и вуаля! Сразу стало видно как изменился код. Так что, ей богу, не стоит считать, что компилятор сделает за тебя ВСЕ.


Дата: Июн 11, 2004 00:07:56

Black_mirror

Та-а-ак. Смотрим, смотрим...
Ого. И ты хочешь сказать, что будет быстрее?

А при чем тут new? Это ж отводится на стеке 8-/

<< . 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.091