Rychlé zjištění existence klíče v rozsáhlém poli předaném odkazem rubrika: Programování: PHP

8 rmaslo
položil/-a 19.12.2013

Mějme rozsáhlejší pole předané odkazem. Toto pole může obsahovat i klíče s hodnotou null. Lze "rychle" zjistit existenci klíče, pokud nechceme v array_key_exists používat "call-time pass-by-reference" které je v PHP 5.4 zrušeno?
Test na PHP 5.3

$ar1 = array_fill(1, 10000, 'x');
$ar2 = &$ar1;
$start = microtime(true);
for ($i=1; $i<1000; $i++ )
  {
  array_key_exists(500, &$ar2);
  };
echo (microtime(true) - $start);

Výsledek: 0.00027s

$ar1 = array_fill(1, 10000, 'x');
$ar2 = &$ar1;
$start = microtime(true);
for ($i=1; $i<1000; $i++ )
  {
  array_key_exists(500, $ar2);
  };
echo (microtime(true) - $start);

Výsledek: 0.89531s

Problém obecně souvisí s vnitřní reprezentací proměnné v PHP a je lehce nastíněn v http://phpfashion.com/php-cerna-magie-optimalizace . nicméně tam podle mého názoru není vyřešen, ale jen šikovně obejit. Otázka samozřejmě je jestli ho vyřešit vůbec lze.

odkaz
6 milan.matejcek
odpověděl/-a 28.12.2013
 
upravil/-a 3.1.2014

Ahoj testoval jsem na PHP 5.5 a 5.4 kde funguje toto:

$data = new ArrayIterator(array(1 => NULL));
// EDIT $data = new ArrayIterator([1 => NULL]);
var_dump(array_key_exists(1, $data));
 
 
 
// puvodni kod
$ar1 = array_fill(1, 10000, 'x');
$ar2 = &$ar1;
$start = microtime(true);
for ($i = 1; $i < 1000; $i++) {
    array_key_exists(500, $ar2);
};
echo (microtime(true) - $start);
 
 
// upraveny, lokálně 100x ryhchlejší, mel by jsi dostat vysledek: 0.008...s
$ar1 = array_fill(1, 10000, 'x');
$ar2 = new ArrayIterator($ar1);
$start = microtime(true);
for ($i = 1; $i < 1000; $i++) {
    array_key_exists(500, $ar2);
};
echo (microtime(true) - $start);

Komentáře

  • rmaslo : Jasně, místo pole použít od začátku objekt s ArrayAccess interface ... tím pádem nejsou žádné problémy s přepisováním původního kódu, není potřeba dělat žádné syntaxtické "hnusy" okolo klíčů obsahujících tečky a objekt se předá funkci array_key_exists referencí, takže nedochází k žádnému kopírování. A vzhledem k tomu, že toto pole / objekt se vytváří na jediném místě programu není problém toto místo upravit. A ArrayIterator je samozřejmě první a nejlogičtější třída co pro objekt s ArrayAccess použít. Velmi hezké. 30.12.2013
  • milan.matejcek : Není zač, jsem rád že to pomůže. 3.1.2014

Pro zobrazení všech 9 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.