Palestra apresentada por mim, Felipe Ribeiro, na PHP Conference Brasil 2009 mostrando os novos recursos do PHP 5.3 no que diz respeito a estruturas de dados
2. Felipe Ribeiro
Graduando (concluinte) em Ciência da Computação na
UFCG
Zend Certified Engineer - PHP5
Trabalha como desenvolvedor Web e consultor com
foco em performance e escalabilidade de Websites
Experiência em grids computacionais e sistemas
distribuídos
Membro fundador do grupo PHP-PB
Contribuidor do PHP e Mozilla Camino
8. Arrays
Um array é uma das mais simples estruturas de dados.
Associa um índice a um valor
Normalmente o índice é um número (inteiro)
No PHP, o array convencional funciona como uma
tabela Hash, e o índice pode ser uma string
No PHP, o array tem tamanho dinâmico
10. SPLFixedArray
Array de tamanho fixo
Índices numéricos inteiros (0 <= n < tamanho do array)
Mais rápido
Implementa as interfaces Iterator, ArrayAccess e
Countable da SPL, que permitem lidar com um
SPLFixedArray como um array convencional
foreach
Acesso direto aos índices ($array[$i])
count()
11. SplFixedArray implements Iterator, ArrayAccess, Countable
{
/* Methods */
public __construct ( int $size )
public int count ( void )
public mixed current ( void )
public static SplFixedArray fromArray ( array $array [,
boolean $save_indexes ] )
public int getSize ( void )
public int key ( void )
public void next ( void )
public bool offsetExists ( int $index )
public mixed offsetGet ( int $index )
public void offsetSet ( int $index , mixed $newval )
public void offsetUnset ( int $index )
public void rewind ( void )
public int setSize ( int $size )
public array toArray ( void )
public bool valid ( void )
}
12. $array = new SPLFixedArray(5);
$array[0] = 'foo';
$array[3] = 'bar';
var_dump(count($array)); //int(5)
var_dump($array[4]); //NULL
var_dump($array[5]); //Uncaught exception
'RuntimeException' with message 'Index invalid or
out of range'
14. Benchmark #1
(criando e preenchendo um novo Array)
Elementos Array (μs) SPLFixedArray(μs) Razão
10 9 11 0.818
100 55 50 1.100
1000 527 441 1.195
10000 6490 4726 1.373
100000 91524 55808 1.640
15. Benchmark #1
(criando e preenchendo um novo Array)
Array SPLFixedArray
100000
75000
Tempo (μs)
50000
25000
0
10 100 1000 10000 100000
Elementos
16. Benchmark #2
(acessando índices aleatórios de um Array)
function acessos_aleatorios($array, $acessos)
{
$max = count($array)-1;
for ($i = 0; $i < $acessos; $i++) {
$array[rand(0,$max)];
}
}
17. Benchmark #2
(acessando índices aleatórios de um Array)
Elementos Array (μs) SPLFixedArray (μs) Razão
(1 milhão de acessos) (1 milhão de acessos)
10 2250005 2242573 1.003
100 2198150 2245209 0.979
1000 2205867 2247230 0.982
10000 2186140 2303941 0.949
18. Benchmark #2
(acessando índices aleatórios de um Array)
O acesso aos elementos de um array
é feito em O(1) - tempo constante
independente do tamanho do array
20. SPLDoublyLinkedList
Adição, remoção, operação de iteração, acesso à
cabeça e à cauda em O(1)
Localização de um nó em O(n)
Usada na implementação de:
SPLStack
SPLQueue
Implementa as interfaces Iterator, ArrayAccess e
Countable da SPL, que permitem lidar como um array
convencional:
foreach, acesso direto aos índices, count()
38. SPLHeap
A maneira mais simples de manter uma coleção
sempre ordenada
Max Heap - Highest first out
Min Heap - Lowest first out
Duas operações
Insere (adiciona à coleção e ordena)
Remove (remove a raíz)
40. SPLHeap
(mantendo uma estrutura equivalente com Array)
function insert(&$array, $element) {
$array[] = $element;
sort($array); //rsort no max heap
}
function extract(&$array) {
return array_shift($array);
}
41. SPLMaxHeap
Cada nodo é menor do
que ou igual ao nodo
pai, de acordo com
algum critério de
comparação
50. Benchmark #5
Array SPLMinHeap
20000000
15000000
Tempo (μs)
10000000
5000000
0
10 100 1000 10000
Elementos
51. SPLHeap
Nem sempre você quer fazer comparações diretas de
elementos, as vezes é preciso ordenar de acordo com
atributos de objetos
É possível estender a classe SPLHeap com o seu
próprio método de comparação
52. SPLHeap
class Campeonato extends SPLHeap {
public function compare($time1, $time2) {
if($time1->pontos == $time2->pontos) return 0;
return $time1->pontos < $time2->pontos? -1:1;
}
}
55. SPLPriorityQueue
Apesar de ser uma fila, é implementada usando um
heap
Elementos com maior prioridade saem primeiro
Ao inserir um elemento, atribui-se uma prioridade para
ele
A análise de performance é análoga à do
SPLMaxHeap, com a diferença apenas do critério de
ordenação
59. SPLObjectStorage
É uma estrutura de dados que relaciona chaves e
valores, como um mapa.
Pode-se ignorar os valores e armazenar só chaves,
fazendo a estrutura se comportar como um Set
Essa estrutura não garante nenhuma política de acesso
ou ordenação
60. SplObjectStorage implements Countable, Iterator, Traversable, Serializable,
ArrayAccess
{
/* Methods */
public void addAll ( SplObjectStorage $storage )
public void attach ( object $object [, mixed $data ] )
public boolean contains ( object $object )
public int count ( void )
public object current ( void )
public void detach ( object $object )
public mixed getInfo ( void )
public int key ( void )
public void next ( void )
public boolean offsetExists ( object $object )
public mixed offsetGet ( object $object )
public void offsetSet ( object $object , mixed $info )
public void offsetUnset ( object $object )
public void removeAll ( SplObjectStorage $storage )
public void rewind ( void )
public string serialize ( void )
public void setInfo ( mixed $data )
public void unserialize ( string $serialized )
public boolean valid ( void )
}
61. // Set
$s = new SplObjectStorage();
$o1 = new StdClass;
$o2 = new StdClass;
$o3 = new StdClass;
$s->attach($o1);
$s->attach($o2);
var_dump($s->contains($o1)); // bool(true)
var_dump($s->contains($o2)); // bool(true)
var_dump($s->contains($o3)); // bool(false)
$s->detach($o2);
var_dump($s->contains($o1)); // bool(true)
var_dump($s->contains($o2)); // bool(false)
var_dump($s->contains($o3)); // bool(false)
62. // MAP
$s = new SplObjectStorage();
$o1 = new StdClass;
$o2 = new StdClass;
$o3 = new StdClass;
$s[$o1] = "data for object 1";
$s[$o2] = array(1,2,3);
if (isset($s[$o2])) {
var_dump($s[$o2]);
}