Professional Documents
Culture Documents
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
Menu
17 Comments
PHP is one
unique
language where
the array data
type has been
highly
generalized to
suit a very
broad set of
use cases. For
example, in PHP
you can use an
array to create
both ordered lists as well as dicts (key/value pairs or maps)
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
1/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
$array[12] = 1;
$array[1] = 2;
$array[17] = 3;
foreach ($array as $num)
echo "$num\n";
1
2
3
2/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
3/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
The above diagram illustrates what the array would look like
in memory. Where the individual blocks (in purple) depict
the bytes in memory with their designated starting
addresses, and the offset depicts where each integer is
stored (in blue). So as you can see the entire 16 byte
block of memory is evenly divided up into 4 bytes, each
signifying our 4 integers and now its really simple to
understand this array.
4/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
5/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
dict = {}
dict[12] = 1
dict[1] = 2
dict[17] = 3
for key in dict:
print dict[key]
2
1
3
6/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
array(4) {
[4]=>
int(1)
["foo"]=>
string(3) "bar"
[-16]=>
bool(true)
[5]=>
string(3) "baz"
}
7/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
8/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
((n1)*(n2)/
2 ) or less.
It is entirely possible to have 100% hash collision in a PHP
array and its a lot simpler than you think. PHP sees array
keys as either one of two things. Either its an int or its a
string. If its an int producing 100% collision is a rather
trivial task. You simply take the size of the array to the
nearest power of 2 and produce keys that increment in
multiples of that size until youve filled the size of the array.
At this stage you have 100% hash collision, meaning
youve exhausted the above cost, which is the worst
possible scenario. To give you an idea hashing a ~65K
(2^16) element array with 100% collision can take up to
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
9/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
10/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
And there you have it! Now we can get the pointer to the
first bucket at offset 2 of our C Bucket Array, which points
to Bucket3. Once we get to Bucket3 we simply verify the
Key member of the bucket to make sure its the element
were looking for and if its not we check the Next member
to get the next bucket and keep going until we find the
element we need. In our case Bucket3 does indeed have a
Key member of -16, which is exactly what we want.
Iterating Arrays
There are quite a few misconceptions when it comes to
traversing a PHP array and what is or is not the
fastest/slowest or most efficient means of traversal. Im
going to do my very best to help debunk any myths or
misnomers you may have heard about such processes. The
key thing to remember here is that for the majority of use
cases no micro-optimizations are necessary since most of
the time each of the methods described here should work
just fine for the bulk of the PHP user base.
First, Id like to start by debunking the myth that a foreach
loop is faster than using a for loop, once-and-for-all. If you
want the tl;dr version its that for loops are faster than
foreach loops in every scenario. However, this does not
mean that one should chose a for loop over a foreach loop
to iterate arrays strictly based on the performance factor.
Lets examine the details a bit more closely to understand
why.
Here I ran a bench mark against both a foreach loop and a
for loop using the same array on both PHP 5.3 and 5.4
release branches. The first row shows a test where all we
did was iterate over the array with no statements in the
body of the loop. The second tests shows what happens
when we make modifications to the array from within each
loop.
PHP 5.3
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
PHP 5.4
11/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
foreach
for loop
foreach
loop
for loop
loop
0.025086
0.012185
0.007306
0.004201
seconds
seconds
seconds
seconds
0.139499
0.027206
0.048462
0.011421
seconds
seconds
seconds
seconds
12/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
$array = range(1,100000);
$start = microtime(true);
foreach ($array as $key => $value) {
$array[$key] += 1; // Invokes COW
}
$end = microtime(true);
$time = $end - $start;
printf("Completed in %.6f seconds\n", $time);
13/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
foreach (COW)
foreach (refere...
for loop
350.000
400.000
450.000
500.000
550.000
1
2
3
4
5
6
7
$array = range(1,100000);
$start = microtime(true);
foreach ($array as $key => &$value) {
$value += 1;
}
$end = microtime(true);
unset($value); // make sure you destroy the
reference
8 $time = $end - $start;
9 printf("Completed in %.6f seconds\n", $time);
Pay special attention to line 7 where we unset the
variable we used as a reference in order to destroy the
reference. Otherwise, you could fall into some
unexpected behavior if you continue to use the same
variable later on.
Here are the results of the bench mark using a foreach loop
with a reference in order to modify the array during the
loop. Compare that to the use of a for-loop to do the same
thing and they are actually quite comparable this time. In
the tests where foreach invokes COW behavior we see a
performance difference of up to 400% in PHP 5.4 and more
than 500% in PHP 5.3 (there have been significant
optimizations in the PHP engine since 5.4 that account for
these dramatic increases in performance). Here weve
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
14/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
closed the gap quite a bit and can hardly see any real
performance differences.
PHP 5.3
foreach
loop
for loop
PHP 5.4
foreach
loop
for loop
0.034114
0.027206
0.011769
0.011421
seconds
seconds
seconds
seconds
$array = array(1,2,3,4);
echo 'key($array): ' . key($array) . "\n";
/* let's move the pointer */
echo 'next($array): ' . next($array) . "\n";
15/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
09
key($array): 0
next($array): 2
1
key($array): 2
2
key($array): 3
3
key($array): 0
4
key($array): 1
key($array): 1
1
bool(false)
2
bool(false)
3
bool(false)
4
bool(false)
16/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
Your PHP script is run in two phases. The first phase is the
parsing phase, where the interpreter reads, tokenizes, and
then lexes your PHP code. The second phase is the
compilation and execution phase where the interpreter
compiles your PHP code down into bytecodes (called
opcodes) and then executes them. During the execution
phase you can run a hook into the Zend engine and ask it
to give you the opcodes as they are generated/executed.
Heres the code we used
1
2
3
4
5
6
<?php
$array = array(1,2,3,4);
foreach ($array as $key => $value) {
echo "$key => $value\n";
}
?>
Heres what the opcodes for the foreach loop would look
like
Line
OPCODE
INIT_ARRAY
ADD_ARRAY_ELEMENT
ADD_ARRAY_ELEMENT
ADD_ARRAY_ELEMENT
ASSIGN
FE_RESET
IS_VAR $2
FE_FETCH
IS_VAR $3
ZEND_OP_DATA
ASSIGN
ASSIGN
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
Return
IS_TMP_VAR
~0
IS_TMP_VAR
~0
IS_TMP_VAR
~0
IS_TMP_VAR
~0
IS_TMP_VAR
~5
17/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
10
ADD_VAR
IS_TMP_VAR
~7
11
ADD_STRING
12
ADD_VAR
13
ADD_CHAR
14
ECHO
15
JMP
16
SWITCH_FREE
17
RETURN
IS_TMP_VAR
~7
IS_TMP_VAR
~7
IS_TMP_VAR
~7
IS_UNUSED
18/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
array(5) {
[4]=>
int(1)
["foo"]=>
string(3) "bar"
[-16]=>
bool(true)
[5]=>
string(3) "baz"
["array2"]=>
array(2) {
[0]=>
string(3) "PHP"
[1]=>
string(6) "Arrays"
}
}
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
19/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
20/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
function.
1
2
3
4
5
6
7
array(1) {
[0]=>
&string(10) "Hello PHP!"
}
21/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
22/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
array(2) {
[0]=>
&string(10) "Hello PHP!"
[1]=>
string(43) "This element only exists in the local scope"
}
array(1) {
[0]=>
&string(10) "Hello PHP!"
}
array(2) {
[0]=>
&string(10) "Hello PHP!"
[1]=>
&string(43) "This element only exists in the local scope"
}
array(1) {
[0]=>
&string(10) "Hello PHP!"
}
No More Arrays!
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
23/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
PHP
arrays
DJBX33A
for-loop
multidimensional arrays
foreach
iterating
php internals
GoogleGuy
View all posts by GoogleGuy
Related Posts
PHP OOP: Objects Under The Hood
Sneak Peek
The Hood
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
24/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
Hirvine
Reply
unreal4u
Reply
michael stevens
Reply
Achmad Solichin
October 29, 2012 at 10:59 pm #
Reply
Kate
Reply
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
25/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
Reply
Vladimir S.
Valdimir S.
Reply
Hello, again :)
Ive found an answer for my previous
question, so Im posting it here in case
anyone else is interested in this too.
Bucket structure is defined as follows:
typedef struct bucket {
ulong h;
uint nKeyLength;
void *pData;
void *pDataPtr;
struct bucket *pListNext;
struct bucket *pListLast;
struct bucket *pNext;
struct bucket *pLast;
const char *arKey;
} Bucket;
As you see there are two pairs of pointers:
pListNext/pListLast and pNext/pLast. The
former pair is one, thats mentioned in this
article to maintain relation between buckets
under one record in hash table. And the
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
26/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
Israel Smith
Reply
Martin Konecny
Reply
Aura Acosta
Reply
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
27/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
Rahul A
Reply
sigmato
Reply
Site
Reply
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
28/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
Pingbacks/Trackbacks
1. Sherif Ramadan: A Closer Look Into PHP Arrays:
Detritus -
[...] A Closer Look Into PHP Arrays: What You Dont See
This entry was posted in Web Bookmarks and tagged
php, programming by chris. Bookmark the permalink.
[...]
3. Best-of-the-Web 11 | David Mller:
Webarchitektur -
November 3, 2012
[...] A Closer Look Into PHP Arrays: What You Dont See
PHP Arrays von allen Seiten beleuchtet mit ein paar
Insights in die interne Struktur von PHP selbst. [...]
Leave a Reply
Your email address will not be published. Required fields are marked *
Name (Required)
E-Mail (Required)
Website
You may use these HTML tags and attributes: <a href="" title=""> <abbr
title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code>
<del datetime=""> <em> <i> <q cite=""> <strike> <strong>
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
29/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
Post Comment
Search
Search this site...
Search
Calendar
October 2012
S
9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Aug
Dec
Socialize
31
Tw eet
18
30/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
PHP Functions
PHP Scope
PHP Classes and Objects
PHP User Input
The PHP Project
PHP Corner
The PHP Corner
Your Development
Environment
Compiling PHP 5.4
Install PECL Extensions
The PHP Project
Categories
DNS (2)
MySQL (11)
PHP (26)
Programming (9)
Search (5)
Security (1)
Technology (8)
Uncategorized (8)
Web Hosting (6)
Recent Posts
A Software Project
Journey
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
31/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
32/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
Do Computer Science
Geeks Need Glasses?
Renewable Energy: You
Are Being Lied To
The Internet Blackout:
SOPA
Why You Need a
Database
Remember Me
Load Balancing Software
as a Service
What Programming
Language Should I Learn
Browsing the Web
WebSockets Making
The Web More Useful
Viral Videos and the
Web
Tags
AI artificial intelligence
cloud
data
machines
system
member
memory
mysql objectoriented-programming
online communication
OOP
33/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
programming SaaS
search search engines
shared hosting small
business
social
networking
technology
timeinterval unix unix time
vps
web web
development web
hosting
y2k38 year
2038 problem
Programming
Examples
Here are some random
programming
examples I've put up
over the years when
helping others with
PHP and some other
languages...
Flash Uploader
Written In
ActionScript
A PHP Calendar
PHP Word Cloud
Generator
My MicroController
Emulator Written In
PHP
My PHP Exploit Joke
An Operator
Precedence Parser
written in PHP
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
34/35
29/5/2014
A Closer Look Into PHP Arrays: What You Dont See | Sherif's Tech Blog
https://sheriframadan.com/2012/10/a-closer-look-into-php-arrays/
35/35