Zend / zend_hash.h ve ext / standart / array.c üzerinde okuduktan sonra ben cevabı (Teşekkür Chris ve önerileriniz için bamya) bulduk düşünüyorum.
PHP dizi int ve string anahtarlarının sağlar (anahtar çarpışmalar O arama (c) ve O (n)) zincirleme bir karma tablo. Bu aynı karma anahtar uzaya iki türlü uygun 2 farklı karma algoritmalar kullanır. Ayrıca karma depolanan her bir değer daha önce depolanan değeri ve (bağlantılı liste) sonra depolanan değeri ile bağlantılıdır. Ayrıca, karma iterated nedenle mevcut öğeyi tutmak için kullanılan geçici bir işaretçi yer alır.
array_rand fonksiyonu için yakalama sağlamak için bu anahtar gerçekten rastgele olduğunu, array_rand function rand(0, count($array)) kere dizinin üzerinde yineleme gerekir (O (n )). Aralığında eksik anahtarları olmadığı hiçbir garantisi yoktur çünkü O'da karma tablo ofset (c) zaman taşımak için hiçbir yolu yoktur, çünkü bu.
Normal C dizi özelliklere sahip PHP NO veri türü var demektir çünkü bu keşif biraz, beni rahatsız etti. Şimdi karma aramalarını çok daha hızlı çünkü bu çoğu zaman, Tamam, ama bu faylar array_rand gibi durumlarda aracılığıyla göstermek.
Ayrıca beni rahatsız başka bir şey array_key_exists ve in_array uygulanması arasındaki fark oldu. in_array doğrusal karma aramak zorunda iken array_key_exists, karma arama anahtar dizide olup olmadığını görmek için (O (c) çoğu zaman) kullanır (O (n) .)
Aşağıdaki iki örnek düşünün:
in_array versiyon
$array = range(0, 100000);
if( in_array( $random_key, $array ) ) {
//we found a value
}
array_key_exists versiyon
$array = array_fill_keys( range(0, 100000), NULL );
if( array_key_exists( $random_key, $array ) ) {
//we found a value, err key
}
While the in_array versiyon looks much cleaner and simpler to understand, it's actually very slow on large arrays (O(n)), where array_key_exists (despite is annoyingly long name) is very fast (O(c) or close).
In conclusion:
I wish there was a transparent flag in the zend HashTable data-structure that would be set in cases where the array was created using array_push or array[] = $value that would allow for scaling like a C array instead of a linked list.