Functioiden tehokkuus + muita kysymyksiä?

Kutsun while loopissa paljon functiota, niin onko tehokkaampaa määritellä function tarvitsemat muuttujat ennen main osioita ja sitten vain muutella niitä tarpeen mukaan?

Vai laittaa nuo muuttujat functio kutsun yhteyteen? siis x(muuttuja)

Ja mitä muuta pitää huomioida, kun tarkoituksena on yksinkertaisesti tehokkuus/nopeus, eikä niinkään koodin selkeys jne...


Ja sitten kannattaako functio määritellä inline void functio vai miten?

Vai onko sittenkin tehokkaampaa ottaa jutut pois functioista ja sijoittaa ne itse suoraan koodiin?


Ja onko muuttuja[x][y] hitaampi kuin muuttuja[x]?

Entäs jos muuttuja sisältää paljon tietoa, niin onko järkevämpää käyttää yhtä isoa muuttuja[x] tai jakaa tuo esim kolmeen eri muuttujaan? Siis x on isoluku
14922
Äänestä

Muut lukivat myös

Vastaukset 14

Vanhimmat

mitä tarkoitat main osiolla?
...
varmaankin on tehokkainta olla käyttämättä funktioita, tehdä vaan ne samat hommat siinä samassa loopissa. koodista tulee vain raskaammin luettavaa mutta helpommin debugattavaa. mun ohjelmissa kriittiset ytimet, joita ajetaan loopissa, eivät sisällä yhtään funktio kutsua.(paitsi matemaattisia funktioita kuten sqrt tms) Ytimen kooodin listausta onkin sitten sivukaupalla, jos sitä pitää muuttaa.

Äänestä
  • *mitä tarkoitat main osiolla? *

    Tuolla vastauksista se selvisikin, tuota globaalia muuttujaa tarkoitin, viel vähän hakusessa nämä nimet.

    Äänestä

Tarkkaa vastausta ei varmaan monikaan osaa antaa. Asia riippuu kääntäjästä, sen vivuista ja koodista itsestään.

Yleisesti ottaen kuitenkin kannattaa välttää funktion toistuvaa kutsumista. Jos se on jonkin luupin sisässä ja kääntäjällä on mahdollisuus optimoida se pois sieltä, niin se kyllä sen pyydettäessä tekee. Koita määritellä funktio inlineksi ja sitten koodata koko höskä loopin sisään. Jos eroa tulee, niin eroa tulee. En oikein usko, että parametrien välittämisellä enää olisi sinänsä ainakaan isoa merkitystä (siis välitys vs. globaali).

Kannattaa myös käyttää pointtereita paljon. Niiden kanssa itse data-aluetta ei tarvitse kopioida sinne tänne vaan pelkän osoittimen muistialueen liikuttelu riittää.

"Entäs jos muuttuja sisältää paljon tietoa, niin onko järkevämpää käyttää yhtä isoa muuttuja[x].."

Ks. yllä. Ilman tarkempaa tietoa veikkaisin, että kannattaa luoda oma tietotyyppi ja pointteri (miten tuo suomennetaan oikein?) siihen.

"Ja onko muuttuja[x][y] hitaampi kuin muuttuja[x]? "

Taas riippuu. Toinen on taulukko, toinen kaksoistaulukko. Riippunee kääntäjästäkin. Olettaisin normaalin taulukon olevan hitusen nopeampi, mutta tämä on kyllä melkein puhdas arvaus. Riippuu oletettavasti myös taulukon koosta, tietenkin :)

Huomaa myös, että pelkästään lyhyt koodi ei tarkoita että se olisi nopeaa. Monet nopeat algoritmit ovat toteutukseltaan huomattavan pitkiä ja monimutkaisia. Niin, kannattaa tosiaan myös valita algoritmit tarkkaan ja *ymmärtää* tarkalleen mitä haluaa tehdä.

Ja luupeista kannattaa tehdä semmoisia, että kääntäjällä on mahdollisuus arvata montako kertaa niitä kutsutaan. Tällöin se osaa optimoida ne pois. Ja usein muokattavat muuttujat (tyyliin for-silmukan laskuri) kannattaa määritellä talletettavaksi rekisteriin (register int i tjsp.).

Äänestä
  • Haenkin semmoisia yleispäteviä vihjeitä jolla koodia voi nopeuttaa. Kun tämä C on vielä aika uusi tuttavuus, tosin aikasempaa kokemusta muista kielistä kyl löytyy.

    Kääntäjänä on G (Dev-C (WinXP))


    Noista pointtereista, kannattaako niitä käyttää silloinkin kun muuttujassa on paljon pieniä tietoja ja se on määritelty globaaliksi?
    Kuten, a, b, ......

    Äänestä

että paljon muistia->suuri nopeus, vähän muistia->pieni nopeus.

Kannattaa miettiä mitä tapahtuu kun kutsutaan funktiota: Ensin kaikki parametrit sijoitetaan pinoon (stack). Sitten ohjelmalaskuria (program counter) laitetaan osoittamaan funktion koodia ja laskenta alkaa. Kun laskenta on valmis, pinoa pitää siivota ennen kun voidaan jatkaa.

"Kutsun while loopissa paljon functiota, niin onko tehokkaampaa määritellä function tarvitsemat muuttujat ennen main osioita ja sitten vain muutella niitä tarpeen mukaan?"

Yrität kysyä kannattaako käyttää globaali muuttujia. Kyllä, mutta käytännössä hyöty on todennäköisesti pieni.

"Ja mitä muuta pitää huomioida, kun tarkoituksena on yksinkertaisesti tehokkuus/nopeus, eikä niinkään koodin selkeys jne..."

Käytä funktiokutsuissa muuttujaosoitteita eikä arvoja. Käytä const-määrittelyä niin kääntäjä pystyy optimoimaan koodin sinulle. Samasta syystä kannattaa funktiossa käyttää register-määrittelyä muuttujille joiden sisältö muuttuu tiheään tahtiin (esim. looppilaskuri).

inline-koodi tai makro on nopeampi kuin tavanomainen funktiokutsu mutta vie enemmän tilaa.

"Ja onko muuttuja[x][y] hitaampi kuin muuttuja[x]? "

On. Tietokone ei tunne kun yksiulotteisia taulukoita. Kun se etsii elementin alkukohdan se laskee:

muuttuja(joka on osoite) x * elementipituus(int, char,double...)

Jos on kaksiulotteinen taulukko se laskee:

muuttuja x*rivienLKM*elementtipituus y*elementtipituus.

(tässä saattaa olla fiba. En koskaan muista C:n ja Pascalin ero tapa rakentaa taulukoita, rivit tai sarakkeet ensin, mutta se ei muuta periaatetta).

Nämä vastaukset ovat vain viitteellisia. Tehokkuus johtuu myös monesta muusta asiasta (niistä on kirjoitettu monta paksua kirjaa ;)

Äänestä
  • *On. Tietokone ei tunne kun yksiulotteisia taulukoita. Kun se etsii elementin alkukohdan se laskee: .....*

    Toisinsanoen kaksiulotteiset taulukot kannattaa hajottaa yksiulotteises jos tämä on mahollista?

    Äänestä

niin siitä voi tutkiskella.

Äänestä
  • Omat taidot ei riitä tuohon assemblyn tulkitsimiseen, mutta pitäs joskus ihan kiinostuksen vuoksi opetella tuota assemblyä hieman.

    Äänestä

Onko oikeasti tarvetta tuon tason optimointiin.
Tuolla tasolla vaikuttavia asioita on jo niin paljon ettei siihen kukaan voi yksiselitteisesti vastata.

Mutta jos sinulla on Intel:n prossa ja sellanen kääntäjä jolla saa inline assembleria mukaan niin tässä on visual studion koodia, mutta saat sen varmaan toimimaan muissakin kääntäjissä.
Tuolla funktiolla saa kellopulssin tarkkuudella tietää kauanko kone on ollut päällä. tuolla pääsee kokeellisesti testaamaan asioita.

Mutta tuolla tasolla toimii ainostaan tilastollinen menetelmä, eli aja testattava koodi vaikka 1000000 kertaa niin näet pienenkin muutoksen vaikutuksen ajoaikaan.

Jos oikeasti haluat optimoida niin tuo on ainoa oikea työkalu :)


#pragma optimize("",off)
__int64 RDTSC(void)
{
volatile ULARGE_INTEGER ts;


_asm
{
xor eax,eax
push eax
push ebx
push ecx
push edx
_emit 0x0f ; cpuid - serialise the processor
_emit 0xa2
pop edx
pop ecx
pop ebx
pop eax
_emit 0x0f ; rdtsc
_emit 0x31
mov ts.HighPart,edx
mov ts.LowPart,eax
}



return ts.QuadPart;
}
#pragma optimize("",on)

Äänestä
  • *Onko oikeasti tarvetta tuon tason optimointiin.*

    Periaatteessa kyllä ja ei. Jo mitä neuvoja täällä olen saanut, on koodi nopeutunut siinä 2-5sek paikkeilla. Ja näitä neuvoja pystyy käyttämään myöheminkin hyödyksi. Ja muutenkin haluaisin tietää mitä perusjuttuja voi tehdä optimoimiseksi?

    Onkos olemassa jotain sivustoa jossa vertailtaisiin optimoitua ja ei optimoitua koodia?


    Tuota suoritysaikaa olen testannut clock() functiolla, koodi on suoritettu montakertaa vaihteluiden minimoimiseksi. Joskaan ei 1000000 kertaa, kun tuossa kestäisi jo pien ikuisuus :)

    Äänestä

  • Naega kirjoitti:

    *Onko oikeasti tarvetta tuon tason optimointiin.*

    Periaatteessa kyllä ja ei. Jo mitä neuvoja täällä olen saanut, on koodi nopeutunut siinä 2-5sek paikkeilla. Ja näitä neuvoja pystyy käyttämään myöheminkin hyödyksi. Ja muutenkin haluaisin tietää mitä perusjuttuja voi tehdä optimoimiseksi?

    Onkos olemassa jotain sivustoa jossa vertailtaisiin optimoitua ja ei optimoitua koodia?


    Tuota suoritysaikaa olen testannut clock() functiolla, koodi on suoritettu montakertaa vaihteluiden minimoimiseksi. Joskaan ei 1000000 kertaa, kun tuossa kestäisi jo pien ikuisuus :)

    Useimmiten optimointi kannattaa aloittaa ohjelma loogisen rakenteen miettimisellä. Siinä vaiheessa kun alkaa tulla kysymykseen talukoiden esitysmuoto allaan jo aika syvällisellä tasolla.

    tämä asia vaikuttaa yleensä paljon enemmän kuin yleensä kuvitellaan.

    Äänestä

  • Naega kirjoitti:

    *Onko oikeasti tarvetta tuon tason optimointiin.*

    Periaatteessa kyllä ja ei. Jo mitä neuvoja täällä olen saanut, on koodi nopeutunut siinä 2-5sek paikkeilla. Ja näitä neuvoja pystyy käyttämään myöheminkin hyödyksi. Ja muutenkin haluaisin tietää mitä perusjuttuja voi tehdä optimoimiseksi?

    Onkos olemassa jotain sivustoa jossa vertailtaisiin optimoitua ja ei optimoitua koodia?


    Tuota suoritysaikaa olen testannut clock() functiolla, koodi on suoritettu montakertaa vaihteluiden minimoimiseksi. Joskaan ei 1000000 kertaa, kun tuossa kestäisi jo pien ikuisuus :)

    Hitaampien kokonaisuuksien optimointiin voi käyttää mitä tahansa kello funktiota jos suoritus kestää useita sekunteja.

    Jos optimoidaan pieniä asioita kuten taulukkoviittauksia tai nopeita funktioita on tuo minun lähettämä funktio ainoa mahdollinen tapa päästä kiinni asioihin joiden suoritus aika on alle 0.000001sekuntia. tuolla funtiolla pääsee tarkkuuksiin n. 0.00000001sekuntia kun suorittaa pienen koodin monta kertaa.

    Jos jollakin on parempi menetelmä mitata todella pieniä asioita, olen kiinnostunut tiedosta.

    Äänestä

malli esimerkki pointterien käytöstä

huono koodi:
unsigned char arrTaulu[100];
int iCount;
for(iCount=0;iCount

Äänestä

Jos sinulla on jotakin konkreettista koodia mitä pitäisi optimoida niin voin hyvin katsoa sitä.

vuosien varrella olen optimoinut lukuisia ohjelmia ja koodinpätkiä. Joskus on joutunut koodaamaan assemblerilla kun muuten ei ole riitävästi potkua irronnut.

Joskus on suoritusajat pudonnut jopa 7:tä tunnista 2 minuuttiin.

Äänestä

Kommentoi aloitusta


Naega kirjoitti:

Kutsun while loopissa paljon functiota, niin onko tehokkaampaa määritellä function tarvitsemat muuttujat ennen main osioita ja sitten vain muutella niitä tarpeen mukaan?

Vai laittaa nuo muuttujat functio kutsun yhteyteen? siis x(muuttuja)

Ja mitä muuta pitää huomioida, kun tarkoituksena on yksinkertaisesti tehokkuus/nopeus, eikä niinkään koodin selkeys jne...


Ja sitten kannattaako functio määritellä inline void functio vai miten?

Vai onko sittenkin tehokkaampaa ottaa jutut pois functioista ja sijoittaa ne itse suoraan koodiin?


Ja onko muuttuja[x][y] hitaampi kuin muuttuja[x]?

Entäs jos muuttuja sisältää paljon tietoa, niin onko järkevämpää käyttää yhtä isoa muuttuja[x] tai jakaa tuo esim kolmeen eri muuttujaan? Siis x on isoluku

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu