Jump to content
php.lv forumi

Foreach optimizācija


DarkSide

Recommended Posts

Nū... ka jau teica.. jāiet cauri ar array_keys... Un nevis vienam līmenim, bet visiem trīs..

Tas jau arī bija, ko es sākumā piedāvāju, bet tas īpaši neesot līdzējis, jo problēma nevis ciklos, bet gan kodā, kas iekš tā cikla.

Edited by GedroX
Link to comment
Share on other sites

  • Replies 39
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

"Aaaa...."

 

A kur tu izmanto šo staffu? Imho tādu kluci apstrādāt online ir neprāts... Jātaisa kaut kāds batch-job, smuki konsolītē.

 

Starp citu, tas nav nekas slikts, ka izmanto daudz atmiņas... Ja ir uzdevumus un tam nepieciešama atmiņa, tad to vienkārši lieto...

 

A ko jūs domājat, skriet ciklā pa 10Mb kluci (PHP taisa masīvu kopijas), viekt operācijas...

Imho jāizmanto references ar masīviem. jāskatās pilnais kods ko tu tur dari.

 

PHP5 arī atbalsta references foreach ($arr AS &$value)

Edited by Delfins
Link to comment
Share on other sites

A kur tu izmanto šo staffu? Imho tādu kluci apstrādāt online ir neprāts... Jātaisa kaut kāds batch-job, smuki konsolītē.
Projekts nopietns un jau ~ gadu tiek lietots in real life. Problēma tur, ka pa šo gadu ir saradies vairāk datu nekā sākotnēji tika prognozēts.
Starp citu, tas nav nekas slikts, ka izmanto daudz atmiņas... Ja ir uzdevumus un tam nepieciešama atmiņa, tad to vienkārši lieto...
Problēma ar lielo aizņemto atmiņas daudzumu rodas uz webservera uz kura griežas šis projekts. Webserveris ir Linux+Apache un kautkāda man nesaprotama iemesla dēļ Apache acīmredzot nokillo procesus, kas aizņem vairāk par apmēram 50Mb RAM. Itkā webservera admini dievojās, ka nekas tāds navētu būt un nekādu ierobežojumu Apache servisam uz webservera nav uzlikti, bet anyway - rezultāts ir viens - "Zero sized replay" vai arī "Page can't be found".
A ko jūs domājat, skriet ciklā pa 10Mb kluci (PHP taisa masīvu kopijas), viekt operācijas... Imho jāizmanto references ar masīviem. jāskatās pilnais kods ko tu tur dari.
Ikdienas darbā šādas konstrukcijas protams netiek izmantotas un ikdienā strādājot (datu ievade, meklēšana, labošana utt.) ar projektu viss ir ok. Šādi brīnumaini masīvi man sanāk lietot veidojot tādas lielākas atskaites par ilgākiem laika periodiem. Tur sanāk daudz datu, kas tiek pieprasīti no MySQL un atgrieztais resultset pēc tam tiek ieparsēts strukturētā masīvā (manā piemērā $arrData), kas pēc tam ar šiem cikliem tiek sakārtots, pārkārtots, saskaitītas visādas starpsummas utt. un ieparsēts objektā, kas satur 2-dimensiju masīvu + dažas definīcijas (piemēram, colspan, rowspan utt), kas savukārt ir tas masīvs no kura tiek noģenerēta un atgriezta HTML tabula (faktiski HTML&bonusi, lai var ielasīt Excelī). Problēma sanāk ar to, ka atlasāmie dati mazāk nekādā gadījumā nepaliks - paliks tikai vairāk, līdz ar to visa tā apstrāde ir jāpārtaisa tā, lai nerītu tik daudz atmiņas, jo 200Mb tikai vienai atskaitei tas nav maz :(
PHP5 arī atbalsta references foreach ($arr AS &$value)
PHP5 diemžēl šobrīd lietot nevaru, jo prasība ir lai viss griežas uz PHP4. Varbūt ar laiku arī nāksies uz PHP5 pāriet, bet tad vajadzēs pārkodēt un testēt stipri daudz ko (a projekts nav mazais) - it sevišķi visu kas darbojas ar objektiem (PHP5 piemēram ir funkcija clone(), savukārt PHP4 noklonēt objektus varēja ar vienkāršu obj1=obj2).
Link to comment
Share on other sites

Tad nošaujies...

Vai arī pārtaisi reportus, kas pa taisno veidos HTML-u (SQL-ā smuki sasortēt un sagrupēt kā vajag)

 

Man jau tāda pati problēma.. pat ja veic atskaiti pa 1 mēnesi... Un es uzreiz izvadu HTML-ā un kopsummas masīvā... nevis visu kluci masīvā un tad taisu atskaiti... Un tici man, ir tādas pašas sarezģītas atskaites... (dinamiski gan pa X, gan pa Y)

 

PS: visticamāk ir uzlikts mem_limit vai nu apacim vai kernelim

Link to comment
Share on other sites

ar mazām optimizācijām var panākt diezgan daudz. papēti vai pašu struktūru/datu izvades veidu nevari pamainīt.

bij man arī daži brīnumi pieredzēti - no db datus vilka baigi lēni (reāli uz browsera bremzēja.. izpildes laiks ap 2-3sec).. sākumā ilgi pētīju visus foreachus un vēl sazin ko, bet tur neko tādu neatklāju - bik optimizēju un sanāca nedaudz nedaudz mazāks izpildes laiks... pēctam izdomāju palūrēt uz pašu db - protams: indexi vispār salikti nebija. saliku un tad kā konfektīte - uz kādām 0.2 sec ripo :)

Link to comment
Share on other sites

Problēma ar lielo aizņemto atmiņas daudzumu rodas uz webservera uz kura griežas šis projekts. Webserveris ir Linux+Apache un kautkāda man nesaprotama iemesla dēļ Apache acīmredzot nokillo procesus, kas aizņem vairāk par apmēram 50Mb RAM. Itkā webservera admini dievojās, ka nekas tāds navētu būt un nekādu ierobežojumu Apache servisam uz webservera nav uzlikti, bet anyway - rezultāts ir viens - "Zero sized replay" vai arī "Page can't be found".

To nedara apache bet gan php ar memory_limit settingu..

 

Vēl piemetot 5cas kapeikas pie tā visa ja ir zināšanas un vēlme var taisīt operacijas ar shared memory, proti datus nedublēt (piemēram kā to dara tas pats foreach) bet visi procesi strādā ar vienu apjomu..

Link to comment
Share on other sites

Hmm - doma jau vispār laba - taisīt tā, lai selekc uzreiz jau atgriež HTML tables rindiņas, taču kā tādu selektu uzrakstīt, ja atskaites struktūra ir diezgan, teiksim tā, īpatnēja. Lūk, piemērs:

 

1) Ir tables CONTRACT (cid,cname), ORDERS(oid,cid,oname), WORKS(wid,oid,wname).

 

2) Selekta princips varētu būt apmēram tāds (jālieto LEFT JOIN):

SELECT c.cname, o.oname, w.wname
FROM contract c 
LEFT JOIN orders o ON (c.cid=o.cid AND o.is_deleted='F')
LEFT JOIN works w ON (o.oid=w.oid AND w.is_deleted='F')
WHERE c.is_deleted='F'

3) Nepieciešamā rezultāta tabula:

CNAME   | ONAME  | WNAME
--------+--------+--------
ccc_1   | ooo_11 | www_111
--------+--------+--------
	|		| www_112
--------+--------+--------
ccc_2   | ooo_21 |
--------+--------+--------
ccc_3   |		|
--------+--------+--------
ccc_4   | ooo_41 | www_411
--------+--------+--------
	|		| www_412
--------+--------+--------
	| ooo_42 | www_421
--------+--------+--------
totals: ...................

 

Jautājumi:

1) Vai WHERE c.is_deleted='F' nevar kautkā arī pārcelt pie FROM nemainot selekta ideju, līdzīgi kā o.is_deleted vai w.is_deleted?

2) Rezultāta tabulā mēģināju attēlot praktiski visus iespējamos variantus, man kautkā nav ideju kā pārrakstīt šo selektu tā, lai iegūtu tādu rezultāta tabulu (ideja ir tā, ka piemēram ccc_1 parādās tikai 1.rindiņā un tālākajās saistītajās rindiņās to vairs neatkārto, līdzīgi arī ar ooo utt...) Oracle Query Builder ir tāda funkcija BREAK, kas dara ko līdzīgu, bet kā kautko tādu uzrakstīt iekš MySQL ar vienu SELECTu netieku gudrs.

3) Vēl dažām kolonnām derētu totals apakšā? To gan laikam ar to vienu selectu nevarēs dabūt. Plus vēl ir dažas atskaites vēl kreetīniskākas, kur vajag arī subtotals pa grupām (piemēram, subtotals zem ccc_1 grupas).

Link to comment
Share on other sites

1) Kamdēl tas nepieciešams?

2) To tak var izdarīt ar php.. Salīdzini ar iepriekš izvadīto vērtību ja sakrīt tad neizvadi ja nesakrīt tad izvadi un atceries.

3) Šādus subresultus ar var skaitīt ar php, viens interger mainīgais aizņems pāris baitus :)

Link to comment
Share on other sites

1) Kamdēl tas nepieciešams?

2) To tak var izdarīt ar php.. Salīdzini ar iepriekš izvadīto vērtību ja sakrīt tad neizvadi ja nesakrīt tad izvadi un atceries.

3) Šādus subresultus ar var skaitīt ar php, viens interger mainīgais aizņems pāris baitus :)

1) nav tik būtiski, vienkārši domāju, lai es visus is_deleted nosacījumus varu izvākt no WHERE, lai smukāk izskatās - bet nu pofig.

2,3) Nu es jau to arī tāpēc daru ar PHP ar tiem nežēlīgajiem foreachiem.

 

Par memory_limit, man uz izstrādes vides (Win+Apache+PHP4) memory_limit=8M un viss izgriežas (pat ja Apache process TaskManager var redzēt, ka noēd brīžiem 200Mb RAM), bet uz produkcijas vides (Linux+Apache+PHP4) memory_limit=50M un procesi kas apēd vairāk par ~50Mb RAM neizgriežas...

Kā tā var būt? Vai tiešām sanāk tā, ka Windows tas PHP parametrs ir pie pak..ļas, bet Linuxam nē???

Link to comment
Share on other sites

Selektam nav nevainas... Imho var iztikt bez tā lielā masīva..

Kā jau Roze teica, pietiek ar atcerēšanos... attiecīgi ar loģiskajiem bloķiem var uztaisīt gan kopsummas un atkartotos tektus nerādīt..

 

Es tieši tā arī daru savos reportos un tas strādā..

Link to comment
Share on other sites

Vēl viens patups jautājums par MySQL (offtopic šeit, bet saistīts ar iepriekš runāto). Es lietoju MySQL 5.x un MyISAM datubāzi. MyISAM cik saprotu nevar veidot datubāzes funkcijas un procedūras. MySQLam bija vairāki tie datubāzes veidi un kādā no tiem šķiet varēja taisīt built-in funkcijas, procedūras, trigerus utml.

Tātad jautājums ir - kā saucās tas MySQL 5.x datubāzes veids un vai kāds no Jums to lieto. Ideja vienkārša - varbūt visu to parsēšanu un kopsummu gatavošanu utt. uztaisīt kā MySQL procedūru, kas atgriež pilnībā noformatētu HTML tabli rezultātā uz PHP un viss. Līdzīgu variantu esmu taisījis vienam citam projektam ar IIS,ASP,Oracle - šansē tīri labi - ASP padod Oracle funkcijai tikai atlases parametrus un Oracle funkcija jau atgriež atpakaļ pilnībā noformatētu HTML tabli kā stringu (Oraclē CLOBu).

 

+ Jautājums - kā un vai iespējams būtu šai gadījumā pārkonvertēt datus no MySQL MyISAM uz MySQL xxxx?

Edited by DarkSide
Link to comment
Share on other sites


×
×
  • Create New...