» »

[ Teorija ] "premature optimization is the root of all evil"

[ Teorija ] "premature optimization is the root of all evil"

BigWhale ::

Tole je rekel Vesoljc v eni drugi temi, se strinjate, se ne strinjate?

Jaz se naceloma ne strinjam.

BlueRunner ::

Prezgodnje karkoli je vedno vzrok za največ težav in največje težave, saj začetni koraki vedno pogojujejo naslednje korake. Posledično to pomeni, da je odpravljanje procesne napake, ki se je pojavila v začetnem koraku najtežje, saj to povzorči ponovitev dela na vseh naslednjih korakih. Težava je samo v temu, da ni možno natančno določiti kdaj je primeren trenutek za uporabo nekega postopka, v trenutku same odločitve. Pravilna ocena, da je bil nek postopek uporabljen prezgodaj ali prepozno, je možna šele takrat, ko je celoten proces zaključen, oziroma, ko pride do težav pri izvedbi procesa.

Ergo: če se je z optimizacijo začelo, in, če je ta optimizacija povzročila težave v nadaljnih korakih, potem je bila optimizacija vsekakor prezgodnja (premature) in posledično tudi izvor težav v procesu razvoja. Če pa optimizacija ni povzročila težav, to pomeni, da ni bila prezgodnja, kar seveda pomeni, da to ni bila "premature" optimizacija. Vsekakor je stavek "premature optimization is the root of all evil" verjetno vzet iz konteksta, s čemer je njegova sporočilna vrednost postala enakovredna stavku "Ta stavek je resničen." Stavek samega sebe izpolnjuje, saj je njegova sporočilna vrednost enaka ne glede na to, ali se odločimo, da je stavek resničen, ali pa ne. Če je bila optimizacija prezgodnja je povzročila težave, kar pomeni, da prezgodnje optimizacije povzročajo težave. Na drugi strani pa težav morda ni bilo, kar pomeni, da optimizacija ni bila prezgodnja, kar seveda pomeni, da ni mogla biti vzrok težavam.

Veliko bolj zanimivo pa se je pogovarjati o optimizaciji sami: Kdaj je optimizacija smiselna? Kakšna optimizacija je smiselna? Ali optimizacija poveča kompleksnost procesa? Ali optimizacija vpliva na zasnovo testov? Na kateri točki je primerno vpeljati optimizacijo? Kako optimizacijo nadzorovati? Kako vrednotiti stroške optimizacije glede na izboljšane rezultate? Ali je dopustna optimizacija, ki spreminja semantiko sistema? in še in še in še....

Matek ::

BlueRunner, a se nisi malce prevec zafilozofiral? Ce jaz prav razumem zadevo, je vprasanje dokaj jasno - a se splaca zelo zgodaj zaceti z optimizacijo, ali je boljse najprej zakljuciti neke funkcionalne celote in sele potem optimizirati.
Bolje ispasti glup nego iz aviona.

BlueRunner ::

Ali lahko vnaprej definiraš kdaj je preveč zgodaj? Konec koncev se optimizacijo ne dela samo v kodi, kot jo vidi večina ljudi, optimizacijo se lahko izvaja že pri načrtovanju sistema. Ali je to prezgodaj ali ne, pa je velikokrat težko povedati vnaprej. Samo če gledaš odločitev za nazaj (hindsight is 20-20) lahko zagotovo rečeš, da je neko prihodnjo težavo povzročila optimizacija. Če jo je, je bila optimizacija prezgodnja. Če je ni, potem optimizacija ni bila prezgodnja.

Kar se tiče pa stavka, pa bom vedno vztrajal, da se stavke vsaj v kontekstu programiranja gleda samo dobesedno. Če govorimo o nekih delovnih postopkih pri razvoju programske opreme, potem ne govorimo o "Jožetu, ki bo zril en jarek," temveč govorimo o "uporabi rovokopača s katerim bomo na trasi od A do B izkopali 120cm globok in 60cm jarek." Če nekdo napiše ekvivalent "problematične odločitve povzročajo probleme," je napisal natančno to. Nikakor pa ni napisal "nekatere odločitve povzročajo probleme - imenujemo jih problematične." "Prezgodnja optimizacija povzroča težave" nikakor ni isto kot "če začnem optimizacijo zelo zgodaj, bom imel težave - optimizacija je lahko prezgodnja." Če programiraš, potem ne ugibaš, temveč definiraš in se trudiš biti dosleden. Če ne znaš niti vprašanja postaviti natančno in čim manj dvoumno, potem imaš tudi z odgovori težave.

'FireSTORM' ::

Odvisno v katerem primeru.
Če vzameš najprej neko simple rešitev ki je zelo počasna in da potem optimiziraš moraš spremenit tričetrt kode potem se ne strinjam.
Kot je pa tam v moji temi, v mojem problemu kjer pri optimizaciji nebom imel večjega problema, saj se bo šlo le za spreminjanje seznama, klici in rezultati bodo pa ostali enaki potem se pa strinjam.

Odvisno tudi od osebnosti.
Če je programer po osebnosti tak da mu je vseeno če en problem obdeluje 3 tedne in prečeše pol spleta za težave, ali če je programer tak ki hoče najprej dobre rezultate neglede na hitrost in šele potem izboljšuje hitrost izvajanja.

Končno bi se strinjal z tem in z tem se tudi strinja sistem učenja programiranja.
Kako bi blo če bi vsakega začel učit programiranja z C ko pa še nima niti osnov kako bi naj programiranje zgledalo in potekalo.
Those penguins.... They sure aint normal....

Vesoljc ::

ta izjava definitivno ni genericna, in je po pravici povedano pobrana z gamedev.net, kjer z njo "proji" strasijo zelence ;)

in naceloma se precej strinjam s teboj BW. kot c++ programer prekleto dobro vem, da "kr zacet kodirat" je velko sranje. ce se le da (in se mora!) je treba zadeve najprej narisat ter premislit kako problem resit z cim manjso porabo (mem, cpu). kot tak sistem zalaufa, pa po potrebi stopi v igro se drug korak optimizacije... to alpa rewrite kode ;)

ampak ponavadi pa izjava leti na zacetnike v programiranju (no offense firestorm), ki se prevec ubadajo sz samo kodo, kot pa dejanskim problemom.
Abnormal behavior of abnormal brain makes me normal...

'FireSTORM' ::

Offense? Zakaj? Saj sem res začetnik in vsaka kritika je dobrodošla, ker se iz nje probam čim več naučit.
Those penguins.... They sure aint normal....

Irbis ::

Na optimizacijo je pametno paziti že pri sami zasnovi programa - lahko to precej bolj vpliva na hitrost, kot potem natančno pisanje posameznih funkcij.
Seveda je pa tudi odvisno od problema. Če je stvar dovolj zapletena, da na začetku težko predvidiš vse in je treba še precej spreminjati stvari, potem je bolje, da ni preveč optimizirano, ker je laže popravljati.

StratOS ::

Šele tedaj, ko je potreba po optimizaciji bi rekel, da je ta potrebna, kajti ne vemo kakšen zajeten kup podatkov bomo optimizirali ter na kakšen način, kaj je sploh (zaradi čega) smo začeli optimizacijo ( hitrost,podatki, ostale možnosti ...), tako da predčasna optimizacija ne glede na te podatke in strukturo ter veličino sploh ni priporočljiva.
"Multitasking - ability to f##k up several things at once."
"It works better if you plug it in."
"The one who is digging the hole for the other to fall in is allready in it."

Jean-Paul ::

Nekaj bo že na tem, saj za tem stavkom (poleg Vesoljca in še koga) stoji nihče drug kot veliki D.E.K. Vendar je izjava v resnici izvzeta iz (časovnega) konteksta.

link, lank

Zgodovina sprememb…

darkolord ::

Ja, s tem stavkom je v originalu bila mišljena "hardcore" optimizacija.

Dober programer IMHO zna itak producirat dovolj optimizirano kodo, da to ni prevelik problem. Fine-tuning se pa itak vedno naredi na koncu.

Takoj na začetku začet s hardcore optimizacijo (razen pač v posebnih primerih, ampak takih je dandanes vedno manj) je lahko precejšen overkill - precej preveč časa se lahko porabi za optimizacijo na čisto nepotrebnih mestih, ker še ni dovolj dobre ideje o poteku celotnega procesa. Sem videl že veliko takih, ki so določene (standardne) funkcije na novo šli pisat v ASM (in MOGOČE kje prihranili kak cikel), je bila pa celotna rešitev zaradi slabše logike/dizajna na koncu vseeno precej počasnejša, kot bi lahko bila. Pa je razvoj trajal precej dlje.

Torej če povzamem: veliko večino (pravih) bottleneckov se da odkrit (in ustrezno obidet) že med osnovnim razvojem. Da se pa takoj na začetku lotiš neke splošne hardcore optimizacije se mi pa ne zdi preveč smiselno. Se pa seveda to lahko spremeni glede na potrebe in vrsto aplikacije.

Zgodovina sprememb…

Thomas ::

Tale tema je "rekurzivna". Bomo že na začetku vseh programiranj optimizirali potek?

Če se bomo recimo odločili, da je prezgodnje optimiranje zlo, smo tako optimizirali vsa bodoča programiranja, saj se prezgodnjih optimiziranj ne bomo šli.

Ovbe, ovbe ... s tem smo zagrešili eno zgodnjo optimizacijo, ergo greh.

Če se bomo pa odločili, da se zgodnje optimizacije vendarle smemo iti, potem - potem smo se paradoxu izognili. LAHKO se jih gremo.

Tko.
Man muss immer generalisieren - Carl Jacobi

darkolord ::

Samo je razlika v nivoju teh optimizacij ;)

CCfly ::

Ta izrek ima svoje diametralno nasprotje, ki se ga na žalost trenutno ne spomnim. Pomen slednjega je v tem da se optimizacijam v smeri algoritmične časovne kompleksnosti ne smeš izogibati, ostale optimizacije pa so odvečne in potencialno škodljive.
Sicer je že Darko več ali manj razložil.

edit: typo.
"My goodness, we forgot generics!" -- Danny Kalev

Zgodovina sprememb…

  • spremenilo: CCfly ()

BigWhale ::

Stvari je treba optimizirati v zacetku tako, da ti je bottleneck vedno I/O, branje in pisanje na disk oziroma "v" nek kabel. Takrat prakticno izgine potreba po optimiziranju CPU operacij, ker vedno cakas na disk.

Pri CPU zahtevnih operacijah, so pa stvari precej drugacne. V ASMju pisat nekaj je dandanes verjetno ze nesmisel. Se pa splaca optimizirat stvari tam kjer se veckrat pojavlja rekurzija in pa pogosto klicanje ene in iste funkcije.

Senitel ::

Po mojem pa tudi pri CPU zahtevnih operacijah ASM še ni izpadel iz igre. Compilerji še vedno niso tako hudimano dobri ko pride do milijona različnih varijant SSE... Ne boš pa šel zato pisat pol programa v ASM-ju.

BigWhale ::

Tole sem se spomnil...

> Odvisno tudi od osebnosti.

To je mozno samo pri 'nedeljskih' programerjih. Ce delas na kaksnem vecjem projektu in z vec ljudmi, potem se bo verjetno treba prilagoditi. Osebnost gor ali dol. :) Tri tedne se ne bo nihce z eno optimizacijo ukvarjal. Razen, ce ni resnicno kljucnega pomena za celotno skupino. :)

Tr0n ::

Ce se prevec osredotocis na optimizacijo v zacetnih fazah aplikacije, potem v bistvu bolj malo razmisljas o dodatni funkcionalnosti in nimas nekega celotnega pregleda. Pa verjetno tudi cas izgubljas ko se igras z optimizacijo, ko se program ni niti koncan.

BigWhale ::

Gah! To ce sam pises. Ce pa delas nekaj vecjega, potem pa imas vso 'dodatno funkcionalnost' ze na papirju in razdelano in ves kaj bos delal.

Tiste malenkosti, pa se sproti spomnis in skodiras.

tsh2 ::

najbolj važno je, da program nima hroščev (se ta beseda uporablja v slovenščini?). najbolje je v začetku vse, vključno s hitrostjo in porabo spomina, premisliti in narediti kompleten in natančen načrt programa. jaz bi rekel da je "izvor vsega zla" programiranje brez načrta ali pa s slabim načrtom. programiranje je treba razdeliti na dva dela: na delanje načrta in pisanje kode, in delanje načrta mora biti težje kot pisanje kode.

jaz bi rekel ravno nasprotno, da je izvor hroščev (i.e. zla) ravno preveliko popravljanje kode naknadno, oziroma mišljenje, "bom že kasneje popravil". od začetka je treba misliti na vse, to pa se da narediti z dobrim načrtom.

Zgodovina sprememb…

  • spremenilo: tsh2 ()

CCfly ::

Na žalost je faza načrtovanja ločena od implementacije še ena tistih lepo zvenečih teorij, ki v praksi izzvonijo v prazno. Od začetka preprosto ne moreš ne misliti na vse ne zajeti vseh zahtev uporabnika (ki jih tako ali tako tipično še sam ne pozna).
Zato se pač faza načrtovanja in implementacije izmenjujeta v zaporedju iteracij. Sicer pa saj so razvojni modeli pri projektih že stara pesem.
"My goodness, we forgot generics!" -- Danny Kalev

tsh2 ::

>"Od začetka preprosto ne moreš ne misliti na vse ne zajeti vseh zahtev uporabnika (ki jih tako ali tako tipično še sam ne pozna)."

Ne mešati stvari. Če programer ne ve, kaj bi uporabnik rad, potem je to drug problem. Mogoče v komunikaciji, ali pa si mora uporabnik prej razjasniti, kaj bi rad. Obenem praviš, da ne moreš misliti na vse zahteve uporabnika? Zakaj pa ne? Sigurno lahko narediš seznam stvari, ki jih mora biti program zmožen opraviti, in to je potem osnova za načrt.

Katere pa so še tiste "lepo zveneče teorije, ki v praksi izzvonijo v prazno"? Jaz sem iz svojih izkušenj prišel do zaključka, da prej rabim dober načrt. Ne programiram več drugače (razen lahkih programov, tam lahko fušaš, bo vseeno.) Če gledaš izvorno kodo programov, jih je tudi zato težko razumeti, ker so brez generalnega načrta. Npr. theory.txt bi moral biti priložen vsakemu delu kode, ki je neodvisen od drugih delov kode.

Zgodovina sprememb…

  • spremenilo: tsh2 ()

CCfly ::

Obenem praviš, da ne moreš misliti na vse zahteve uporabnika? Zakaj pa ne? Sigurno lahko narediš seznam stvari, ki jih mora biti program zmožen opraviti, in to je potem osnova za načrt.

Zelo preprosto, ti nisi uporabnik in on ni programer. On mnogokrat ne ve kaj bi rad, ti dostikrat ne veš kako se bo določena funkcionalnost uporabljala. Pa če imaš še tako dobro izveden zajem zahtev, se seznam spreminja.

Jaz sem iz svojih izkušenj prišel do zaključka, da prej rabim dober načrt.

Nisem rekel da ne rabiš načrta, rekel sem da fazi načrtovanja in implementacije nista ločeni, temveč se izmenjujeta. Preprosto sem se obregnil ob to, da generalni načrt in nato implementacija nista realistični, razen če imaš toliko denarja kot IBM in lahko stranke in svoje inženirje zapreš v hotel za dva tedna.

edit: typo
"My goodness, we forgot generics!" -- Danny Kalev

Zgodovina sprememb…

  • spremenilo: CCfly ()

Thomas ::

Uporabnik ne ve kaj hoče. Vsaj dokler tistega ne dobi. Potem reče da ne mara ali pa reče "še mi tko delej!". V tisti fazi ima verjetno tudi kakšno zelo tehtno pripombo ali idejo.

Za vse pa ne boš naredil nikoli. Izberi samo en del uporabnikov, ki govorijo tvoj jezik.

Pa razvijaj zadevo ob povratnih informacjah tvojih strank.

Vsaj 33% jih raje pošlji h konkurenci, da njej zaserjejo vse.
Man muss immer generalisieren - Carl Jacobi

'FireSTORM' ::

Lol, zakaj že?

Stranka: To pa to hočem še zraven.
Razvijalec: Vredu, stalo bo toliko in toliko zraven.

Zakaj bi konkurenci dajal svoj dobiček?
Those penguins.... They sure aint normal....

Thomas ::

Ker nisi ne Bog, ne Microsoft.

Čeprav prodajaš "samo kruh", je bolje da vseh ni v tvojo štacuno. Z enimi je zguba, drugi bi slabo vplivali na okus tvojih pekarskih izdelkov ...

Čez 50% trga se ne splača hodit.
Man muss immer generalisieren - Carl Jacobi

mspiller ::

Delno bi se strinjal, delno pa ne.

Da pojasnim. Jaz osebno imam nekako dva nacina dela.
Ali zacnem pisati ze kar se da optimiziran algoritm, v primeru, da imam taksen set podatkov, ali pa taksen test case, kjer lahko rezultat preverim sproti.

Po drugi strani, ko to ni mogoce. Potem naredim najprej neoptimalni algoritm, v taksni obliki, ki jo lahko preverim, potem pa delam optimizirano verzijo. Popravke na izboljsanem algoritmu pa testiram, tako da random set podatkov posiljam cez oba algoritma in gledam rezultat. Vsega tega se lotim neodvisno od ostale kode. To sem naprimer na veliko uporabljal na faksu pri kaksen aps2.

Drugace pa optimalno kodo iscem ze sproti, seveda dokler ni potrebe po kaksnih hash tabelah, index tabelah, pregeneriranih tabelah in podobno. To ponavadi pustim za na konec. Je pa optimizacija odvisna tudi od requirementov. Ce je to kaksen kriticen del potem grem zadevo optimizirat, ce je pa to algoritm, ki izvaja redko pa ponavadi ne. Pri nas v sluzbi, se ponavadi kaksnih extremnih optimizacij ne dela, ker nastane problem, cez kaksno leto, ko je potrebno popravljati taksno kodo (se posebi, ce ti nisi avtor). Takrat sicer pomaga, ce je bil narejen tudi neoptimalen, vendar logicno jasen algoritm, ki se ga uporablja za unit testing. Pri raznih seminarskih na faksu je pa to drugace, ker je zivljenska doba algoritma vsega mogoce kaksna ura :).

BlueRunner ::

Kadar se optimizira kodo, se mora vedno vedeti kakšni natančno so cilji optimizacije. To pa zato, ker je cena za optimizacijo kode največkrat žrtvovanje osnovnih načel dobrega programiranja, če ne kar pravilnosti delovanja za vse možne vhodne podatke. Vsaka optimizacija programske kode lahko pripelje do novih napak v delovanju in bolj kompleksne kode, ki vedno manj odraža dejanski postopek - algoritem. Bolj kompleksna koda je tudi manj razumljiva, zaradi česar jo je tudi težje vzdrževati ali pa uporabljati pri drugih aplikacijah. Zaradi vseh teh negativnih lastnosti vsake optimizacije kode, je ta, v večini življenskih situacij, nepotrebna saj imajo jasnost, preglednost in (vsaj približno dokazljiva) pravilnost prednost pred običajno malenkostnimi pridobitvami optimizacije programske kode.

Vsekakor pa je optimizacija dobra in dobrodošla tam, kjer je možno jasno demonstrirati, da je potrebno hitrejše (cpu) ali učinkovitejše (mem, I/O) delovanje programa, optimizacija pa privede do zelo opaznih razlik v delovanju. Če imamo algoritem, katerega zahtevnost je O(n2), potem lahko z optimizacijo pridemo iz npr. 10*n2 na 5*n2. To pa nam pomaga obdelati nekaj več podatkov v nekem doglednem času. Če pa za isti problem obstaja algoritem zahtevnosti O(n), ali pa celo O(Log(n)), tega pa načrtovalec (in ne programer) ne ve, ali pa ne zna, potem takšnega smetja ne morejo rešiti niti največji herojski napori programerjev, ker bo O(n) algoritem pri zadostni količini podatkov vedno prekašal O(n2) algoritem*.

Če je sistem/aplikacija pravilno načrtovana, potem je potreba po optimizaciji resnično minimalna. Če pa ta potreba obstaja, se jo da včasih uganiti, ne pa vedno. Načrtovalec sicer lahko izbere pravilne algoritme in pristope, na koncu pa lahko še vedno pride do problemov, ki lahko zahtevajo optimizacijo. Če pa programer dela optimizacijo "na rezervo", pa lahko takšen programer IMO fuša in se uči kje drugje, ne pa na produktih z znanimi zahtevami in roki. Takšna brezciljna optimizacija je navadno strup, saj vedno naredi veliko škode, dobički pa niso nikoli ne vidni, ne dokazljivi.

-----
* Kot ilustracijo lahko dam primer, ko je nek kandidat algoritem prostorske zahtevnosti O(na) optimiziral tako dolgo, da mu je uspelo v nekaj GiB RAM-a rešiti nekaj, kar običajno porabi nekaj 10 GiB RAM-a. S tem ni spremenil prostorske zahtevnosti algoritma, temveč je samo herojsko podaljšal njegove "muke". Drugi kandidati so našli algoritem prostorske zahtevnosti O(n), z njim pa so problem rešili v nekaj MiB. Čeprav je dokazal, da optimizacijo resnično obvlada, takšnega načrtovalca pač ne potrebujemo.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Automatic Algorithm Invention with a GPU

Oddelek: Znanost in tehnologija
163138 (2546) rasta
»

Digitalna evolucija (strani: 1 2 3 426 27 28 29 )

Oddelek: Znanost in tehnologija
141675417 (25586) pietro
»

Macintosh Plus (1986) proti sodobnemu PC-ju (2007) (strani: 1 2 )

Oddelek: Novice / --Nerazporejeno--
568118 (5407) darkolord
»

Mono bo zavladal Linuxu!

Oddelek: Novice / Ostala programska oprema
152508 (2508) matjazgu
»

Programiranje (strani: 1 2 )

Oddelek: Programiranje
846515 (5113) Thomas

Več podobnih tem