New SPL Features in PHP 5.3

Preview:

DESCRIPTION

http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/

Citation preview

New SPL Features in PHP 5.3

Matthew Turland

TEK-X

May 20, 2010

Hi! My name is…

• Senior Platform Engineer for Synacor, Inc.

• Former author and TE for php|architect

• Author of Web Scraping with PHP

• Past contributor to Zend Framework

• Lead developer of Phergie

• ULL alumni with a BS in computer science

And I work for…

• Provides internet solutions to ISPs, media companies, and advertisers

• International company with offices in Buffalo, New York City, Los Angeles, and Amsterdam

• Clientele includes most of the top 20 cable providers in the United States

• Great company – join us!

What about you?

• Used the SPL before?

• Using PHP 5.3?

• Computer science background?

• Knowledge of data structures?

Pre-5.3 SPL Features

• Classes: ArrayObject, SplFileInfo, SplSubject, SplObserver, etc.

• Iterators: RecursiveIteratorIterator, FilterIterator, LimitIterator, etc.

• Interfaces: ArrayAccess, Countable, Iterator, IteratorAggregate, etc.

• Functions: spl_autoload_register, iterator_to_array, spl_object_hash, etc.

Containers

“A container is a class, a data structure, or

an abstract data type whose instances are

collections of other objects. They are used

to store objects in an organized way

following specific access rules.”

Container (data structure) - Wikipedia

Why containers?

• We already have arrays and strings!

array() 'string'

Two excellent reasons

• Versus traditional arrays, there is potential for:

– Less CPU usage

– Less memory usage

Arrays are (not always) great

• Flexible general purpose container

• Underlying hash table algorithm is not always ideal for the task at hand

Warning: Benchmarks Ahead

• Lies, Outrageous Lies, and Benchmarks

• PHP 5.3.2 compiled on Ubuntu 9.10

• Intel Core2Duo 1.83 GHz, 4 GB DDR2 RAM

• Performance results are shown in executions per second rather than time per execution to avoid really small numbers

• Code and results

The List

SplFixedArray - What

• Like an array, but with a fixed length

• Only allows integers >= 0 for keys

• Can be resized, but at a cost

• Not compatible with array functions

SplFixedArray - When

• It’s best to use this when:

– You know in advance how many elements you want to store (e.g. mysql_num_rows)

– You only need to access elements in sequential order

SplFixedArray - Code

<?php

$a = array();

for ($i = 0; $i < $argv[1]; $i++) {

$a[$i] = $i;

$i = $a[$i];

}

<?php

$a = new SplFixedArray($argv[1]);

for ($i = 0; $i < $argv[1]; $i++) {

$a[$i] = $i;

$i = $a[$i];

}

SplFixedArray - EPS

SplFixedArray - Memory

SplDoublyLinkedList - What

• Mainly intended as a parent class

• Same unlimited size as arrays without the associated hash map algorithm

• Less performance, but more memory efficiency

SplDoublyLinkedList - When

• It’s best to use this when:

– You do not know in advance how many elements you want to store

– You only need to access elements in sequential order

SplDoublyLinkedList - Code

<?php

$a = array();

for ($i = 0; $i < $argv[1]; $i++) {

$a[] = $i;

$i = $a[$i];

}

<?php

$a = new SplDoublyLinkedList($argv[1]);

for ($i = 0; $i < $argv[1]; $i++) {

$a[] = $i;

$i = $a[$i];

}

SplDoublyLinkedList - EPS

SplDoublyLinkedList - Memory

The Stack

SplStack - What

• 2 operations

– Push: [] for both array and SplStack

– Pop: array_pop() vs SplStack::pop()

• Last In, First Out (LIFO)

– The last item pushed onto the top of the stack is the first item that will be popped off of the top of the stack

SplStack - When

• It’s best to use this when:

– You do not know in advance how many elements you want to store

– You only ever need to access the last element you stored

SplStack - Code

<?php

$a = array();

for($i = 0; $i < $argv[1]; $i++) {

$a[] = $i;

}

for($i = 0; $i < $argv[1]; $i++) {

array_pop($a);

}

SplStack - Code (cont.)

<?php

$a = new SplStack;

for($i = 0; $i < $argv[1]; $i++) {

$a[] = $i;

}

for($i = 0; $i < $argv[1]; $i++) {

$a->pop();

}

SplStack - EPS

SplStack - Memory

The Queue

SplQueue - What

• 2 operations

– Enqueue: [] for both array and SplQueue

– Dequeue: array_shift() vs SplQueue::dequeue()

• First In, First Out (FIFO)

– The first item added to the end of the queue will be the first item removed from the front of the queue

SplQueue - When

• It’s best to use this when:

– You do not know in advance how many elements you want to store

– You only ever need to access the remaining element that was stored earliest

SplQueue - Code

<?php

$a = array();

for($i = 0; $i < $argv[1]; $i++) {

$a[] = $i;

}

for($i = 0; $i < $argv[1]; $i++) {

array_shift($a);

}

SplQueue - Code (cont.)

<?php

$a = new SplQueue;

for($i = 0; $i < $argv[1]; $i++) {

$a[] = $i;

}

for($i = 0; $i < $argv[1]; $i++) {

$a->dequeue();

}

SplQueue - EPS

SplQueue - Memory

The Heap

SplHeap - What

• 2 operations

– Insert: [] + sort vs SplHeap::insert()

– Remove: array_shift() vs SplHeap::extract()

• Internally reorders items based on comparison

– SplHeap::compare() can be overridden

• Subclasses

– SplMinHeap

– SplMaxHeap

• Better worst-case scenario performance versus arrays (heap sort versus quick sort)

SplHeap - When

• It’s best to use this when:

– You do not know in advance how many elements you want to store

– You need to access elements in an order based on how they compare to each other

SplMinHeap - Code

<?php

$a = array();

for($i = 0; $i < $argv[1]; $i++) {

$a[] = rand(1, $argv[1]);

sort($a);

}

for($i = 0; $i < $argv[1]; $i++) {

array_shift($a);

}

SplMinHeap - Code (cont.)

<?php

$a = new SplMinHeap;

for($i = 0; $i < $argv[1]; $i++) {

$a->insert(rand(1, $argv[1]));

}

for($i = 0; $i < $argv[1]; $i++) {

$a->extract();

}

SplMinHeap - EPS

SplMinHeap - Memory

The Priority Queue

SplPriorityQueue - What

• Accepts a priority with the element value

• Element with highest priority comes out first

• Priorities may be of any comparable type

• SplPriorityQueue::compare() can be overridden

• Operates similarly to a heap

– In fact, it uses a heap internally for storage

SplPriorityQueue - When

• It’s best to use this when:

– You do not know in advance how many elements you want to store

– You need to access elements in an order based on how priority values associated with those elements compare to each other

SplPriorityQueue - Code<?php

$threshold = $argv[1] * 0.1;

$a = array();

$i = 0;

do {

if ($i <= $argv[1]) {

$a[] = array($i, rand(1, 10));

usort($a, 'priority_sort');

}

if ($i > $threshold) {

array_shift($a);

}

$i++;

} while (count($a));

function priority_sort($a, $b) {

return $a[1] - $b[1];

}

SplPriorityQueue - Code (cont.)<?php

$threshold = $argv[1] * 0.1;

$a = new SplPriorityQueue;

$i = 0;

do {

if ($i < 1) {

$a->insert($i, rand(1,10));

}

if ($i > $threshold) {

$a->extract();

}

$i++;

} while (count($a));

SplPriorityQueue - EPS

SplPriorityQueue - Memory

The Set

The Composite Hash Map

Just pretend the red pills are objects.

SplObjectStorage - What

• Combination of two data structures

– Composite hash map: a hash map with objects for keys; the spl_object_hash() function must be used for arrays to have this capability

– Set: focuses on a group of values rather than individual values with operations like union, intersection, difference, and element_of; no concept of sequential order

• Currently lacks a method for the intersection operation

SplObjectStorage - When

• It’s best to use this when:

– You need to store data using composite (i.e. non-scalar) keys

– You need the ability to access data using set operations more so than accessing it in a particular order

SplObjectStorage - Code<?php

$a = array();

for ($i = 0; $i < $argv[1]; $i++) {

$object = new stdClass;

$a[spl_object_hash($object)] = $object;

}

$a = array();

$b = array();

for ($i = 0; $i < $argv[1]; $i++) {

$a[] = rand(1, $argv[1]);

$b[] = rand(1, $argv[1]);

}

$c = array_merge($a, $b);

$c = array_diff($a, $b);

SplObjectStorage - Code (cont.)<?php

$a = new SplObjectStorage;

for ($i = 0; $i < $argv[1]; $i++) {

$object = new stdClass;

$a->attach($object, $object);

}

$a = new SplObjectStorage;

$b = new SplObjectStorage;

for ($i = 0; $i < $argv[1]; $i++) {

$a->attach((object) rand(1, $argv[1]));

$b->attach((object) rand(1, $argv[1]));

}

$c = clone $a;

$c->addAll($b);

$c = clone $a;

$c->removeAll($b);

SplObjectStorage - EPS

SplObjectStorage - Memory

Thank this guy

• Etienne Kneuss did a lot of the work on the new SPL features in PHP 5.3

Possible future SPL features

• Graphs

– Contain nodes and edges connecting them

– Directional / non-directional

– Cyclic / acyclic

– Connected / unconnected

– Edge costs

• Trees

– Acyclic unidirectional graph

– Hierarchical in nature

Feedback, please!

http://joind.in/1577

That’s all, folks

• Any questions?

• http://synacor.com

• http://matthewturland.com

• me@matthewturland.com

• @elazar on Twitter

• Elazar on the Freenode IRC network