PHP array hash Conflict instance, do you know that inserting 65,536 elements of a constructed key value into a PHP array takes more than 30 seconds? In general, this process takes only 0.1 seconds.
take a look at the following examples:
$size = POW (2, 16);
$startTime = Microtime (true);
$array = Array ();
for ($key = 0, $maxKey = ($size-1) * $size; $key <= $maxKey; $key + = $size) {$array [$key] = 0;
} $endTime = Microtime (true);
Echo ' Inserts ', $size, ' A malicious element needs ', $endTime-$startTime, ' seconds ', ' \ n '; $startTime = Microtime (true);
$array = Array ();
for ($key = 0, $maxKey = $size-1;
$key <= $maxKey; + + $key) {$array [$key] = 0;} $endTime = Microtime (true);
Echo ' Inserts ', $size, ' A common element needs ', $endTime-$startTime, ' seconds ', ' \ n ';
The example above, the results on my machine are as follows:
Inserting 65,536 malicious elements requires 43.1438360214 seconds to insert 65,536 common elements in 0.0210378170013 seconds
Is this difference very exaggerated?!
I introduced in the previous article, after a special construction of the key value, so that every time PHP insert will create a hash conflict, so that the bottom of the PHP array hash table degenerate into a list:
Hash Collision
So every time you insert PHP need to traverse this list, you can imagine, the first time to insert, you need to traverse 0 elements, the second is 1, the third is 3, the No. 65536 is 65,535, then the total need to 65534*65535/2=2147385345 the second traversal ....
So, how does this bond value construct?
In PHP, if the key value is a number, then the hash is the number itself, in general, the Index & Tablemask. Tablemask is used to ensure that the numeric index does not exceed the number of elements that the array can hold, that is, the number of arrays-1.
PHP's hashtable size is 2 of the index, such as if you deposit 10 elements of an array, then the actual size of the array is 16, if you save 20, the actual size is 32, and 63 words, the actual size of 64. When you save more than the current number of elements in the array, PHP will enlarge the array, and the new hash.
Now, let's say we're going to deposit 64 elements (the middle may be expandable, but we just need to know that the final array size is 64 and the corresponding Tablemask is 63:0111111), so if the first time we save the element with a key value of 0, the hash value is 0, The second time we deposited, hash (1000000 & 0111111) of the value is also 0, the third time we use 128, the fourth time with 192 ... It allows the underlying PHP array to hash all elements onto number No. 0 bucket, thus making the hash table degenerate into a linked list.
Of course, if the key value is a string, it is a little more troublesome, but the PHP hash algorithm is open source, known, so the conscientious also can do ...
This article address: http://www.laruence.com/2011/12/30/2435.html