Автор Гілка: про оптимізацію  (Прочитано 7208 раз)

Відсутній Паша

  • Кореспондент
  • ***
  • дописів: 142
  • Карма: +0/-0
  • хайо!
про оптимізацію
« : 2005-12-14 22:46:44 »
У програмі є цикл, що крутиться приблизно мільйон разів. Логічно зробити так, щоб одна ітерація займала найменеше часу. Який оператор швидкіший  :D ? for чи while? Чи може вони однаково компілюються? Що порадите?
debian

WS(Guest)

  • Гість
Re: про оптимізацію
« Відповідей #1 : 2005-12-14 22:53:24 »
оптимізація компілятора в більшості випадків позбовляє сенсу таку "оптимізацію".
ще запитай що швидше ++i vs i++ :)))

Відсутній Паша

  • Кореспондент
  • ***
  • дописів: 142
  • Карма: +0/-0
  • хайо!
Re: про оптимізацію
« Відповідей #2 : 2005-12-15 00:01:25 »
Я про це здогадувавсь. Але ж все таки мільйон ітерацій...
debian

Відсутній MoD

  • Кореспондент
  • ***
  • дописів: 161
  • Карма: +0/-0
Re: про оптимізацію
« Відповідей #3 : 2005-12-15 03:42:52 »
Теоретично for буде трохи швидшим, оскільки має чітко визначену кількість повторень і не потребує перевірки умови виходу. В асемблерному коді це буде просто повторення деякої ділянки коду n разів... А у випадку з while буде ще перевірка умови (типу кількість повторень < 1000000). Але я не думаю, що різниця в швидкодії навіть буде помітною... А взагалі, якщо у вас в середині циклу якісь математичні вирази, то краще їх спочатку спростити за допомогою /dev/hands, порахувати окремо все, що можна порахувати за межами циклу, уникати рекурсій і т.п.

Відсутній DalekiyObriy

  • Літератор
  • ******
  • дописів: 1923
  • Карма: +4/-0
Re: про оптимізацію
« Відповідей #4 : 2005-12-15 15:05:23 »
головне, дядьку, не капелюх, а те, що під ним :) (тобто в середині циклу), але якщо вже є таке нестерпне бажання знати, є два шляхи:
1) скомпілювати обидва варіанти з gcc -S і подивитись асемблерний код
2) скомпілювати обидва варіанти і зробити time myprog (бажано декілька разів)
Fedora 35 (x86-64)

ws(Guest)

  • Гість
Re: про оптимізацію
« Відповідей #5 : 2005-12-15 16:40:52 »
Теоретично for буде трохи швидшим, оскільки має чітко визначену кількість повторень і не потребує перевірки умови виходу. В асемблерному коді це буде просто повторення деякої ділянки коду n разів... А у випадку з while буде ще перевірка умови (типу кількість повторень < 1000000). Але я не думаю, що різниця в швидкодії навіть буде помітною

дивна теорія. :) чому ти вирішив що для цикла фор якись блок буде повторюватися N раз? і чому вважаєш що кількість ітерацій всередені відома на єтапі компіляції?
ось тобі найпростіший варіант
std::vector<InterDat>::const_iterator it, end;
it = sections_.begin();
end = sections_.end();
for(; it != end; ++it)
{
..........

розмір вектора може динамічно змінюватися так що вставити N блоків компілятору навряд чи вдасться  і перевірка умови також є

Відсутній Yaroslav Fedevych

  • Літератор
  • ******
  • дописів: 1069
  • Карма: +0/-0
  • Людина — ніщо, справа — все
Re: про оптимізацію
« Відповідей #6 : 2005-12-15 17:42:08 »
Взагалі-то будь-який цикл в сях можна виразити через for, так що все це syntactic sugar чистої води.

Питання має стояти, як взагалі має виглядати тіло циклу.

Відсутній MoD

  • Кореспондент
  • ***
  • дописів: 161
  • Карма: +0/-0
Re: про оптимізацію
« Відповідей #7 : 2005-12-15 18:54:56 »
Цитата
std::vector<InterDat>::const_iterator it, end;
it = sections_.begin();
end = sections_.end();
for(; it != end; ++it)
{
..........
Ой, чур мене, STL:) Вибачаюсь, був не правий, мислення у мене паскалівське:) Там фіг таке зробиш. Хоча тоді абсолютно не зрозуміла доцільність таких конструкцій в for, теж саме можна і while'ом зробити. В Паскалі ж зрозуміло, що for - не ітеративний цикл (не має можливості обчислення наближення до деякого значення), а тут в нього все, що завгодно можна запхати. Подивився асемблерний вивід обох варіантів у С і побачив, що і там і там використовується порівняння і умовний перехід у будь-якому випадку. Так що, дійсно, використання for чи while ніякої зміни в швидкодії не дасть, а при увімкненій оптимізації тим більш.

WS(Guest)

  • Гість
Re: про оптимізацію
« Відповідей #8 : 2005-12-16 00:07:58 »
Ой, чур мене, STL:)
навіщо "чур"? хоч деякі ідеї в сучасному с++ досить складні, але для професійного програмування іх бажано знати :) а то так і залишишся на 15 років в минулому.
Хоча тоді абсолютно не зрозуміла доцільність таких конструкцій в for, теж саме можна і while'ом зробити.
можно назвати то синтаксичним оверхедом :) але просто зручніше мати такий оператор for, його звичайно можно зімітувати через while, але якщо for сприймається як одна синтаксична конструкція, то анологічний while як 2 - ініціалізація, зміна зміної по якій то все ітерується, перевірка умову і при цьому перші дві конструкції не прив"язані до конкретного місця в коді, відповідно читатися і супортитися такий код буде важче.

Відсутній Паша

  • Кореспондент
  • ***
  • дописів: 142
  • Карма: +0/-0
  • хайо!
Re: про оптимізацію
« Відповідей #9 : 2005-12-16 00:20:12 »
Отже "...маємо шо маємо...".
Я трішки помилився у своїх розрахунках. Насправді ітерацій не мільйон, а мільярд  ::) .
Шматок коду, що тестувався, виглядає так:
Цитата
                //for(i=0;i<BreaksNumber;i++){
             i=0;while (i++<BreaksNumber){
                  n[0]=i*d;
                  n[1]=i*h;
                  a=a0+n[0]+n[1];
                  b=a+d;
                  if (xz > a && xz < b){
                        xz1=xz0*z1*x_z0;
                        yz1=yz0*z1*y_z0;
                        fprintf(outfile,"%lf %lf\n",xz1,yz1);
                  }
}

компілювалося два рази - один з for, інший з while... ... gcc  з опцієй -mmmx... ... ніяких -о чи -О нема. ....Всі змінні за виключенням і та BreaksNumber (unsigned long) мають тип double. Ніяких конструкторів, деструкторів, qt, gtk, tcl, та інше нема -- звичайний С. (Я себе професійним програмістом не вважаю  ::) )

Комп'ютер - celeron tualatin 1300 MHz 256 Mb. ...зараз подивлюсь... ...Calibrating delay loop... 2580.48 BogoMIPS...

Під час запуску програм нічого такого неробилося. Навіть мишу не рухав. Запуски програм проводились по два рази (для статистики  ;) ).

Результати:

for:

real     1m18.192s (+- 0.1s*)
user     1m17.421s (+- 0.1s)
sys      0m0.521s  (+- 0.01s)

while:

real     1m17.724s (+- 0.1s)
user     1m16.974s (+- 0.1s)
sys       0m0.513s (+-0.01s)

*приблизно, на око  ::)

Ну-с, що маємо?
while виявляється випереджає for. Хоча і на якісь 0.3 сик., і це на мільярд ітерацій.
Отже приблизно на 10e-10 сик. на ітерацію  8-)
ps Привіт Пану MoD`y  ;)

« Змінено: 2005-12-16 00:53:43 від lpi »
debian

Відсутній Паша

  • Кореспондент
  • ***
  • дописів: 142
  • Карма: +0/-0
  • хайо!
Re: про оптимізацію
« Відповідей #10 : 2005-12-16 00:59:22 »
Найголовніше забув:
lpi@tx2000:~$ gcc --version
gcc (GCC) 3.3.5 (Debian 1:3.3.5-8)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

lpi@tx2000:~$

debian

Відсутній MoD

  • Кореспондент
  • ***
  • дописів: 161
  • Карма: +0/-0
Re: про оптимізацію
« Відповідей #11 : 2005-12-16 12:52:15 »
Цитата
навіщо "чур"? хоч деякі ідеї в сучасному с++ досить складні, але для професійного програмування іх бажано знати Усмішка а то так і залишишся на 15 років в минулому.
З STL я більш-менш розбираюсь, просто, коли подивився на його реалізацію мені погано стало:D Така складність реалізації заради простоти використання? Я не думаю, що це правильна ідея. Хоча це власне НМД.
Цитата
for:
 
real     1m18.192s (+- 0.1s*)
user     1m17.421s (+- 0.1s)
sys      0m0.521s  (+- 0.01s)
 
while:
 
real     1m17.724s (+- 0.1s)
user     1m16.974s (+- 0.1s)
sys       0m0.513s (+-0.01s)
Ой не вірю я, що так повільно... А той масив n вам же не потрібен ще десь за межами циклу, як і змінні a, b - можна було б обійтись і без них.
« Змінено: 2005-12-16 13:11:31 від MoD »

Відсутній borman

  • Графоман
  • ****
  • дописів: 416
  • Карма: +0/-0
  • Debianizer
Re: про оптимізацію
« Відповідей #12 : 2005-12-16 13:30:22 »
Цитата
...while виявляється випереджає for. Хоча і на якісь 0.3 сек., і це на мільярд ітерацій.
Отже приблизно на 10e-10 сек. на ітерацію.  Круто.
В межах похибки результати співпадають.. Особливо, якщо зважити на наявність fprintf -- хтозна, куди система записувала ваші дані в той чи інший момент часу...
dd if=/dev/zero of=/dev/null

Відсутній Паша

  • Кореспондент
  • ***
  • дописів: 142
  • Карма: +0/-0
  • хайо!
Re: про оптимізацію
« Відповідей #13 : 2005-12-16 15:13:35 »
Без a,b,n  :-/
Цитата
...if (xz < a(0)+i*d+i*h && xz > a(0)+(i+1)*d+i*h){...
операцій множеня тут більше. Чи може я вас неправильно зрозумів?...
Часу багато займає, бо програма обробляла текстовий файл 7.4 Мб, що складається з double цифр (там перед цим фрагментом ще fscanf є).

А взагалі з практичної точки зору це питання безглузде, бо програма не є якоюсь realtime, тому якщо вона буде рахувати на 0.3 с повільніше, то мені від цього "ні холодно, ні жарко"  ;)

ps В ІПФ міста Суми maple деякі задачі по 10 годин рахує. Зараз керівництво замислюється про GRID (Це той, що Sun Miсrosystem розробляеться).
debian

Відсутній MoD

  • Кореспондент
  • ***
  • дописів: 161
  • Карма: +0/-0
Re: про оптимізацію
« Відповідей #14 : 2005-12-16 18:49:07 »
Дійсно, змінну а можна залишити;) Хоча, якщо швидкість для вас великого значення не має, то можете все це залишити задля зручності.