Optimalizace cyklů for(); rubrika: Programování: JavaScript

6 Mlocik97
položil/-a 23.11.2018
 
upravil/-a 23.11.2018

Zdravím,

neviete, jak by šlo optimalizovať cykly for() tak, že počet cyklů je udaný vstupom od používateľa (alebo výstupom inej funkcie), a tento vstup (alebo výstup sa) môže meniť? Čo tým myslím?

Ako príklad dajme že mám kalkulačku, ktorá počíta faktoriál. Mám <input type="number" min="0"> kde uživatel zadáva vstup. Ten vstup sa okamžite zapíše do premennej input.

mám cyklus:

if (input == 0 || input == 1) {
    return 1;
}
var o = 1;
for (let i = 0; i < input; i++) {
    o = o * (input -1);
};
return o;

a premenná o je zas výstup, ktorý sa vypíše na stránke.
Jak spraviť aby ak bol predchádzajúci vstup 5 a zmenil sa na 7, aby cyklus nerátal znova od nultej iterácie), ale aby zobral aktuálny výsledok a na ňom vykonal ďalšie 2 cykly? Ak to vůbec takto jde, čož myslím že moc ne. Problém je že na stránke když zmením vstup trebárs 5x v priebehu 3 sekúnd, a vstupom sú veľké čísla, tak stránka zaťaží viac processor a niekedy začne aj trocha lagovať, pri vstupoch ako "125064752" už sa zmena premietne do výsledku niekedy aj po viac než celých 3-4 sekundách.

https://i.imgur.com/SRnfjkG.png

Komentáře

  • Mlocik97 : ako napadlo ma riešenie, len je problém ho zrealizovať, lebo v cykle for volám ešte externú funkci, kde je ešte jeden cyklus, do ktorého sa predáva skrz parameter druhý vstup. 23.11.2018
  • harrison314 : Hlvne nepouzivat JS na taketo veci, nehodi sa na vypocty ani CPU bound operacie. 26.11.2018
  • ivoszz : Ten požadavek je velice problematický a jde proti osvědčeným postupům. Spíš než měnit cyklus má smysl u některých typů výpočtů cachovat mezivýsledky, což pak může výrazně zrychlit příští výpočty a dosáhnout téhož bez negativních dopadů na srozumitelnost programu. 26.11.2018
odkaz Vyřešeno
6 kohven
odpověděl/-a 26.11.2018

Jak už tu v komentáři psal bofteam, pokud se v tom výpočtu mohu nějakým směrem odpíchnout od záchytných bodů, tak zadrátovat do kódu záchytné body a počítat to od nich.

V dobách 286 a programování her v asembleru bych si netroufl vůbec nic spouštět, kdybych neměl předpočítaný i sin(45) a sin(22.5) :).

Ale pokud by šlo opravdu o faktoriál, tak bych asi zvážil rozsah. Faktoriál pro čísla kolem 1000 je mnohabytové číslo (BTW výrazně přesahující odhadovaný počet protonů ve vesmíru). U faktoriálu 125064752 by už byl možná problém ho vůbec reprezentovat v paměti PC. O obrazovce ani nemluvě.

Komentáře

  • Mlocik97 : faktorial bol priklad. V mojom pripade sa jedna o neco jine. Trebárs ja pri vstupoch X = 0; Y = 100000000; mám výsledok: 9999957311439308. pri vstupoch X = 100000000; Y = 100000000; mám výsledok: 9999992189789644 26.11.2018
  • kohven : Když se ne to kouknu ještě jinak, tak by se ten problém dal chápat taky jako: Jak odhadovat, které mezivýsledky ukládat, na základě již obdržených požadavků. Něco jako: už se v rámci výpočtu blížím k požadované hodnotě, tak si začnu ukládat i její okolí, protože je pravděpodobné, že ho budu brzy potřebovat. Obávám se, že to ale bude vyžadovat i kvalitní doménovou znalost. Hlavní kámen úrazu je v tom "blížím se" a "protože je pravděpodobné". :) 26.11.2018
  • Mlocik97 : presne tak... 26.11.2018
  • kohven : Ze dvou bodů v prostoru si vážně netroufám odhadovat povahu funkce, ale z předešlého popisu jsem pochopil, že mám nějaké diskrétní body v ploše jako definiční obor a pro výpočet f(x,y) potřebuji znát f(x-1,y) nebo možná f(x,y-1) nebo možná f(x-1,y-1). Bez jiných znalostí povahy funkce bych asi z praxe zaznamenával, které body se počítají nejčastěji a nějaký rozumný rozptyl kolem nich. Pak bych vypočítal výsledky pro body, které jsou o kousek (rozptyl) blíž k [0,0], než jsou statistikou nalezené body a zadrátoval do kódu. Od nich bych se pak při počítání odpíchnul. To samozřejmě platí jen v případě, že je funkce po celou dobu existence programu deterministická. 26.11.2018
  • bofteam : Ale tak si přečtěte ten úvodní dotaz. Optimalizace cyklu for VS matematická analýza neznámé funkce, to je trochu rozdíl. Nevím, jaké taková věc může mít reálně využití, aby uživatel měnil vstup 5x za sekundu ? Pokud se jedná o grafy, tak CACHE. Pokud se jedná o fyzikální simulaci, tak WebWorkers API, jinak C, jinak Matlab, jinak FPGA :D 26.11.2018
  • Mlocik97 : no samozrejme že uživateľ bežne zrejme nebude meniť 5x za sekundu vstup, no i tak chcem aby to šlo plynule i kdyby náhodou fakt ten užívateľ ten vstup 5x za sekundu zmenil. Sú to výpočtové funkcie, ktoré áno som plánoval prezentovať aj vo forme grafov. Ten Cashe a medzivýsledky asi budú najzrozumitelnejší spôsob. 26.11.2018
  • Mlocik97 : Tak mám to vyriešené, už to jde omnoho plynulejšie, i když stále nie až tak moc plynule jak by som si to želal. Tak ma napadlo že by tomu určite pomohlo aj to, keby som samotnú funkci obsahujúci cyklus nevolal hneď pri každej zmene vstupu, ale počkal na ustálenie vstupu. Trebárs ak sa 100ms nemenil vstup, zavolať funkciu na výpočet. 27.11.2018
  • kohven : Tak pokud je to o tom, že když chce uživatel další výsledek před tím, než mu doběhl předešlý, tak o ten předešlý už nestojí, tak chceš asi hlavně umět předčasně ukončovat již bežící výpočet. Běží-li to opravdu asynchronně, tak by to neměl být problém. Pak nemusíš dělat 100ms čekání před začátkem výpočtu a může to být ještě plynulejší. Ale musí to být ta asynchronost, kterou naznačoval bofteam. Ne jen uložit jedno volání do fronty, ale pořád pouštět k řeči ostatní volání. 27.11.2018

Pro zobrazení všech 7 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.