Autor | Zpráva | ||
---|---|---|---|
Ropak Profil * |
#1 · Zasláno: 17. 12. 2009, 12:01:27
Mám problém s "Maximum execution time of 30 seconds exceeded". Generuji data jistym matematickým výpočtem dle kriterii zadaných uživatelem. Dat byva hodně a výpočet trvá dlouho. Vetšinou to skonci na výše uvedené chybe. Obavam se že funkce set_time_limit() neni řešení, protože hrozí i vypršení limitu prohližeče.
Jedine co me napada je v pravidelnych intervalech prerusit vypocet a pomoci hlavicky "Location" zavolat znovu sam sebe s tim ze si stav ulozim nekam do session. Jde neco takoveho udelat jeste s tim ze se vypise nejaka informace o stavu procesu? |
||
pollo22 Profil |
#2 · Zasláno: 17. 12. 2009, 14:34:33
Ja by som sa skôr snažil nejak lepšie zoptimalizovať ten vypočet. čo to počitaš že to trva tak dlho?
|
||
mckay Profil |
#3 · Zasláno: 17. 12. 2009, 15:28:42
Ropak:
Nechci se ošklivě zmýlit, ale ještě nikdy se mi nestalo, že by mi vypršel čas provádění skriptu v prohlížeči. Dle mého se všechny výpočty odehrávají na serveru a prohlížeč jen čeká na jeho odpověď, takže by to snad nemělo dělat problémy. (Mám Operu) |
||
Akacko Profil |
#4 · Zasláno: 17. 12. 2009, 20:01:52
Ropak:
O jaký výpočet se jedná? Nešel by nějak zjednodušit (odstranit rekurzi, pokud nějaká je apod.)? Nezacyklí se výpočet? Popř. pošli sem ten výpočet a třeba to někdo vyřeší a pomůže optimalizovat. |
||
tomyx007 Profil |
#5 · Zasláno: 17. 12. 2009, 20:03:46
Pokud cerpas data z databaze, pouzivej indexy apod...Nebo to chce proste optimalizaci skriptu. Takto nejde k tomu vice rici, kdyz nevidime ten tvuj algoritmus...
|
||
imploder Profil |
#6 · Zasláno: 17. 12. 2009, 21:29:17
Ropak:
Výpočet může během svého průběhu generovat nějaký výstup, aby prohlížeč třeba každých pár sekund něco dostal a neměl tak dojem, že server neodpovídá. Funkcí microtime se dá zjistit čas v mikrosekundách. Můžeš si ho na začátku uložit, pak během výpočtu kontrolovat, jestli už není třeba o 5 sekund větší a když je tak vypsat stav výpočtu prohlížeči a uložený čas přepsat aktuálním. Čistější řešení by bylo, aby se ten výpis volal přerušením (aby se čas nemusel kontrolovat a nezpomaloval se tím výpočet) - to nevím, jestli v PHP jde udělat. |
||
Ropak Profil |
#7 · Zasláno: 18. 12. 2009, 08:20:36
pollo22:
Ne ne zadna rekurze ani nekonecna smycka. Generuji náhodné události s hustotou pravdepodobnosti zavislou dle zadani uzivatele (ke kazde udalost se pak prirazujen nekolik parametru). Muze se jednat radove o x*10e6 udalosti, ktere potrebuji naladovat do db. Algoritmus nedokazu udelat v mysql. pollo22: vidis to me nenapadlo posilat neco prubezne prohlizeci, to by bylo asi nejjednodussi. |
||
nightfish Profil |
#8 · Zasláno: 18. 12. 2009, 09:05:50
Ropak:
„Muze se jednat radove o x*10e6 udalosti, ktere potrebuji naladovat do db“ v tom případě doufám, že používáte vícenásobné inserty, protože sunout takového množství řádků do databáze po jednom je za trest (a trvá to dlouho) co se limitu prohlížeče týká - vcelku běžně mi v prohlížeči běží skript třeba hodinu (Firefox) |
||
Ropak Profil |
#9 · Zasláno: 18. 12. 2009, 09:15:10
nightfish:
ano, ale jen po jednotkach az stovkach. Zalezi to na prubehufunkce v danem kroku. |
||
peta Profil |
#10 · Zasláno: 18. 12. 2009, 12:29:36
Ropak:
Pokud bys muj server zatezoval 30s v kuse, asi bych ti ten script brzo odpojil. Uz to bylo receno, dej sem kod vypoctu. Idealne celeho souboru, link na nej. Pravdepodobne misto vyuziti pameti vyuzivas mnozstvi jinych prostredku, treba jak pisi, 30x volas databazi nebo neco podobne. Bez kodu tezko rici. Muzes zkouknout bigdump.php (google), ktery se pouziva misto phpadminu na nasoukani treba 60MB sql kodu do databaze. |
||
TomášK Profil |
#11 · Zasláno: 18. 12. 2009, 16:03:40
Pro načítání velkého množství záznamů je dle mých zkušeností lepší LOAD DATA než INSERT. Při vícenásobném insertu jsem musel řešit omezení na počet vkládaných záznamů, tuším, že se to pohybovalo v desítkách tisíc a LOAD DATA bylo znatelně rychlejší - odhadem desetkrát. Přesná čísla si nepamatuju.
|
||
Časová prodleva: 4 dny
|
|||
Ropak Profil |
#12 · Zasláno: 22. 12. 2009, 10:40:23 · Upravil/a: Ropak
No dobra, je to trosku delsi, ale snad pochopitelne.
function flushsql(&$sql,&$sqlvalues) { $sql .= ";"; $result = mysql_query ($sql, $GLOBALS["link"]); $sql = "INSERT INTO `dbdb`.`".$_SESSION["a"]['tbname']."` (`sec`, `us`, `amp`, `len`) VALUES "; $sqlvalues=0; } // .... // generujeme hity do db $hittime = new uTime; $sql = "INSERT INTO `dbdb`.`".$_SESSION["a"]['tbname']."` (`sec`, `us`, `amp`, `len`) VALUES "; $sqlvalues=0; $printed = 0; // vyrabime hity a ukladame je do db for ($i=0;$i<$_SESSION["aesrc"]['itvcnt'];$i++) { // pro kazdy interval $a = &$_SESSION["a"]['itv'][$i]; for($t=$a["start"]->sec; $t<$a["end"]->sec; $t++) { // jdeme sekundu po sekunde $c = (float)(getfv($a, $t) + getfv($a, $t+1))/2.0; // cetnost jako prumer funkcni hodnoty na zacatku a konci periody while ($c>=1.0) { $hittime->sec = $t; $hittime->us = (integer)((random_0_1()*1000000) + ($a["tvar"]*(random_0_1()-0.5))); //pridame neurcitost casu $hittime->Normalize(); // us musi byt v intrvalu <0,1000000) $amp = random_0_1()* ($a["ampmax"] - $a["ampmin"]) + $a["ampmin"]; // amp nahodne v zadanem intervalu if ($hittime->sec > $a["start"]->sec && $hittime->sec < $a["end"]->sec) // hity ktere padnou mimo zadany interval ignorujeme { if ($sqlvalues>0) $sql .= ", "; $sql .= "(FROM_UNIXTIME(".$hittime->sec."), '".$hittime->us."', '".$amp."', '".(integer)($amp*100)."')"; $sqlvalues++; if ($sqlvalues>100) flushsql($sql,$sqlvalues); } $c -= 1.0; } if (random_0_1()<$c) // mene nez jedna za sekundu { $hittime->sec = $t; $hittime->us = (integer)(random_0_1()*1000000 + ($a["tvar"]*(random_0_1()-0.5))); //pridame neurcitost casu $amp = random_0_1()* ($a["ampmax"] - $a["ampmin"]) + $a["ampmin"]; if ($hittime->sec>$a["start"]->sec && $hittime->sec<$a["end"]->sec) { if ($sqlvalues>0) $sql .= ", "; $sql .= "(FROM_UNIXTIME(".$hittime->sec."), '".$hittime->us."', '".$amp."', '".(integer)($amp*100)."')"; $sqlvalues++; if ($sqlvalues>100) flushsql($sql,$sqlvalues); } } if (time() >= $printed + 3) { // aktualizace počítadla nejdříve za tři vteřiny echo "<script type='text/javascript'>document.getElementById('counter').innerHTML = 'Interval:".$i.", Cas:".$t."';</script><noscript>.</noscript>\n"; ob_flush(); flush(); $printed = time(); } } if ($sqlvalues>0) flushsql($sql,$sqlvalues); } // tady by mela byt db naplnena Dopredu upozornuji, ze je to docasna verze. Kod v cyklu While a za IF je nyni identicky a prijde do funkce. |
||
nightfish Profil |
#13 · Zasláno: 22. 12. 2009, 10:50:49
Ropak:
chtělo by to nějaké profilování... tzn. určit, při které činnosti skript stráví nejvíce času - jestli při tom výpočtu, nebo při provádění dotazů do DB... k těm SQL dotazům: „(FROM_UNIXTIME(".$hittime->sec."), '".$hittime->us."', '".$amp."', '".(integer)($amp*100)."')“ tam, kde se vkládají číselné hodnoty, odstraňte ty apostrofy, mysql pak nebude muset přetypovávat FROM_UNIXTIME($hittime->sec) by se dalo nahradit za "'".Date("Y-m-d H:i:s", $hittime->sec)."'" - ale jestli to přinese zrychlení musíte vyzkoušet sám |
||
DoubleThink Profil * |
#14 · Zasláno: 22. 12. 2009, 12:33:09
mckay:
„Nechci se ošklivě zmýlit, ale ještě nikdy se mi nestalo, že by mi vypršel čas provádění skriptu v prohlížeči.“ Server obvykle během vykonávání skriptu udržuje s klientem spojení - to může trvat teoreticky nekonečně dlouho. |
||
Ropak Profil |
#15 · Zasláno: 22. 12. 2009, 12:43:57 · Upravil/a: Ropak
DoubleThink:
To je dobre. Jen aby vydrzel uzivatel. Ty vypisy co jsou tam udelane pomoci JS nejak nefunguji (asi AVG) |
||
Časová prodleva: 15 let
|
0