Jump to content
php.lv forumi

Mainīgo apstrāde pēc references lēnāka, nekā pēc vērtības (?)


slicer

Recommended Posts

Laikam jautājums tiem, kas PHP zina līdz pamatiem.

Absurda situācija.

 

Optimizējot ciklu, nonācu pie slēdziena, ka strādājot ar mainīgo referencēm iekš PHP (jeb līdzīgi kā tas ir C++ valodā ar pointeriem) ātruma ziņā tikai izbojā visu pasākumu.

 

$t1 = microtime_float();
$searcher = new Searcher($pro, $order, $conn);
$set = $searcher->Search();

while (!$set->EOF)
{
 $pro = $set->fields; //šādi strādā ātrāk
 $pro = &$set->fields; //šādi strādā lēnāk
 ... //visādas darbības ar mainīgo $pro
}

$t2 = microtime_float();
echo $t2- $t1;

//ķipa saliek pašreizējo laiku
function microtime_float()
{
  list($usec, $sec) = explode(" ", microtime());
  return ((float)$usec + (float)$sec);
}

 

Kur prikols?

Link to comment
Share on other sites

PHP izmanto hašmapus... C/C++ izmanto reālas adreses.

Tāpēc pirms kaut ko darīt PHP vajag dabūt adresi hašmapā pēc references (1papildus darbība), nekā uzreiz veikt darbības ar tā saukto `mainīgo`

 

PS: vismaz tās ir manas tādas domas.

Edited by Delfins
Link to comment
Share on other sites

Atradu haš-mapa updeitošanu...

 

#define UPDATE_DATA(ht, p, pData, nDataSize)											\
if (nDataSize == sizeof(void*)) {													\
	if ((p)->pData != &(p)->pDataPtr) {												\
		pefree_rel((p)->pData, (ht)->persistent);									\
	}																				\
	memcpy(&(p)->pDataPtr, pData, sizeof(void *));									\
	(p)->pData = &(p)->pDataPtr;													\
} else {																			\
	if ((p)->pData == &(p)->pDataPtr) {												\
		(p)->pData = (void *) pemalloc_rel(nDataSize, (ht)->persistent);			\
		(p)->pDataPtr=NULL;															\
	} else {																		\
		(p)->pData = (void *) perealloc_rel((p)->pData, nDataSize, (ht)->persistent);	\
		/* (p)->pDataPtr is already NULL so no need to initialize it */				\
	}																				\
	memcpy((p)->pData, pData, nDataSize);											\
}

Link to comment
Share on other sites

Jā. Principā tā ir hash_update() funkcijas realizācija no php_hash PECL.

Ja daudz jāciklojas un datu apjoms apmaiņai šajos ciklos ir neliels, tad anyway nesanāks izdevīgi.

 

Ok. Skaidrībā tikām. Paldies vēlreiz.

 

P.S. Info: hash_update f-ju jau no dzimšanas var lietot PHP 5.1.2 lietotāji. Pārējiem tā jākabina klāt manuāli no šejienes: http://pecl.php.net/package/hash

Link to comment
Share on other sites

slicer: tu jauc divas dažādas lietas - hešsummas (tavs hash_update). Un heš-maps, kurā php glabā mainīgos (līdzīgi kā std::hash_map no C++ STL bibliotēkas), par kuru runā Delfins. Tb asociācija strings -> mainīgais. References gadījumā sanāk divas reizes vērsties šim map'am klāt, taču nereferences - tikai vienu, tā sapratu no Delfina teiktā. Atmiņas vs ātruma tradeoffs.

Link to comment
Share on other sites

tieši tā... visu var apskatīties iekš PHP sourcēm...

References pamatā tiek lietotas f-jām priekš parametriem, nevis `ceļa saīsināšanai`.

 

relatīvi nepareizi:

$prop = & $myObj->fields;
$prop->gugu();
$prop->gaga();

 

relatīvi pareizi:

function dodo(& $obj)
{
  $obj->gogo();
}

 

tavā variantā pareizāk būtu :

$set->Search();

$res = $set->DoAfterSearch();

 

un iekš tās f-jas arī būs paša objekta mainīgā apstrāde

Link to comment
Share on other sites

Hashsum no hashmap es atšķiru.

Bet tagad ir putra.

 

Delfīna hash updeitošanas direktīva ir no Zend dzinēja (zend_hash.c sourcefails).

Ja jau, Delfīn, tu pats saki, ka tā ir hashmap update funkcija, tad ko viņa dara Zend dzinējā?

 

Neesmu PHP eksperts, bet kaut kā no googlē salasītā konteksta nopratu, ka šī funkcija ir arī PHP dzinēja pamatā un strādā tieši ar PHP mainīgo hashmap. Un visu šo hash funkciju kopu var izmantot, lai pa tiešo manipulētu ar hashmap. Ir pat piemēri, kā has_update() var izmantot piemēram 700Mb liela faila satura iebakstīšanai pa tiešo hashmapā, neaiztiekot mainīgo instances.

 

Par to, kas ir relatīvi pareizi un nepareizi. Nav nepareizi lietot pointerus, lai atvieglotu koda rakstīšanu (saīsinot ceļu pie kautkādagaraobjekta->apakšobjekta), taupītu atmiņu un paātrinātu procesu. Viss Windows ir uzrakstīts uz mēmiem pointeriem.

 

Nu skaidrs - PHP references nav efektīvas un pointeru nav. Lieta slēgta. :)

Link to comment
Share on other sites

PHP reference ir efektīvas, ja tu tos izmanto lietas labā (padod f-jai).

Galvenais, ka tu saprati, ka PHP nav pointeru!

Un kāpēc tu brīnies, ka PHP piedāvā pieeju savam iekšējam hash-mapam!? Protams ka viņš uztaisīs 100-un-1 pārbaudi, kad izsauc tāda zema līmeņa f-ju.. bet tas neo nenozīmē...

 

C++ piemēram var arī rakstīt inline ASM kodu, un nepareizi inicializējot reģistrus tev programma vnk krešosies... ne jau kompilātors būs vainīgs, bet tavas līkas rokas.

 

Galvenais lasīt manuāļus/google, saprast kas ir kas, nevis kliegt, ka kods bremzē...

Link to comment
Share on other sites

Hashsum no hashmap es atšķiru.

Uz brīdi tā neizskatījās, jo iedevi manuāli uz hešfunkcijām.

 

Delfīna hash updeitošanas direktīva ir no Zend dzinēja (zend_hash.c sourcefails).

Ja jau, Delfīn, tu pats saki, ka tā ir hashmap update funkcija, tad ko viņa dara Zend dzinējā?

Kā ko dara? PHP mainīgos glabā hašmapā. Tāpēc tā arī ir tur, lai tu varētu definēt jaunus mainīgos un iegūt jau definētu mainīgo vērtības.

Link to comment
Share on other sites

×
×
  • Create New...