SPL Datastructures

10,214 views

Published on

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

Published in: Technology
1 Comment
32 Likes
Statistics
Notes
  • Estou começando o estudo de PHP. Porém o conteudo parece mostrar novas funcionalidades do php 5.3 de uma forma simples.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
10,214
On SlideShare
0
From Embeds
0
Number of Embeds
5,379
Actions
Shares
0
Downloads
191
Comments
1
Likes
32
Embeds 0
No embeds

No notes for slide
  • SPL Datastructures

    1. 1. SPL Datastructures Estruturas de dados e algoritmos em PHP Felipe Ribeiro http://feliperibeiro.com felipernb@php.net @felipernb
    2. 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
    3. 3. SPL Classes e interfaces nativas
    4. 4. Estruturas de dados
    5. 5. Estruturas de dados Armazenamento Organização Conjuntos
    6. 6. PHP 5.3 traz SPL Datastrucutres
    7. 7. O bom e velho Array não era suficiente?
    8. 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
    9. 9. <?php $array = array(); $array[0] = "foo"; $array['bar'] = "baz"; $array[525] = "xpto"; echo $array[0]; ?>
    10. 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. 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. 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'
    13. 13. Benchmark #1 (criando e preenchendo um novo Array) $array = array(); for( $i = 0; $i < $argv[1]; $i++) { $array[$i] = $i; } $array = new SPLFixedArray($argv[1]); for( $i = 0; $i < $argv[1]; $i++) { $array[$j] = $j; }
    14. 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. 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. 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. 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. 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
    19. 19. SPLDoublyLinkedList cabeça cauda
    20. 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()
    21. 21. SPLStack Pilha
    22. 22. SPLStack LIFO (Last In, First Out) Duas operações Push (Empilha) Pop (Desempilha)
    23. 23. SPLStack Com Array eu também posso fazer isso! array_push ou [ ] array_pop Mas o Array não garante que você possa fazer SÓ isso!
    24. 24. SPLStack $pilha = array(); $pilha[] = 1; array_push($pilha, 2); $pilha[] = 3; var_dump(array_pop($pilha)); // int(3) var_dump(array_pop($pilha)); // int(2) var_dump(array_pop($pilha)); // int(1)
    25. 25. SPLStack $pilha = new SPLStack(); $pilha[] = 1; $pilha->push(2); $pilha[] = 3; var_dump($pilha->pop()); // int(3) var_dump($pilha->pop()); // int(2) var_dump($pilha->pop()); // int(1)
    26. 26. Benchmark #3 $array = array(); for($i = 0; $i < $argv[1]; $i++ ) { array_push($array, $i); } for($i = 0; $i < $argv[1]; $i++) { array_pop($array); }
    27. 27. Benchmark #3 $stack = new SPLStack(); for($i = 0; $i < $argv[1]; $i++ ) { $stack->push($i); } for($i = 0; $i < $argv[1]; $i++) { $stack->pop(); }
    28. 28. Benchmark #3 Elementos Array (μs) SPLStack (μs) Razão 10 48 41 1.17 100 467 354 1.32 1000 4656 3966 1.17 10000 51473 42463 1.21
    29. 29. Benchmark #3 Array SPLStack 60000 45000 Tempo (μs) 30000 15000 0 10 100 1000 10000 Elementos
    30. 30. SPLQueue Fila
    31. 31. SPLQueue FIFO (First In, First Out) Duas operações: Enqueue (enfileirar) Dequeue (desenfileirar)
    32. 32. SPLQueue Com Array eu também posso fazer isso! array_push ou [ ] array_shift Mas, novamente, o Array não garante que você possa fazer SÓ isso!
    33. 33. Benchmark #4 $array = array(); for($i = 0; $i < $argv[1]; $i++) { $array[] = $i; } for($i = 0; $i < $argv[1]; $i++) { array_shift($array); }
    34. 34. Benchmark #4 $queue = new SPLQueue; for($i = 0; $i < $argv[1]; $i++) { $queue[] =$i; } for($i = 0; $i < $argv[1]; $i++) { $queue->dequeue(); }
    35. 35. Benchmark #4 Elementos Array (μs) SPLQueue (μs) Razão 10 32 43 0.7 100 338 412 0.8 1000 12472 3915 3.2 10000 1091477 39242 27.8 100000 581828231 418623 1389.9
    36. 36. Benchmark #4 Array SPLQueue 6E+08 4.5E+08 Tempo (μs) 3E+08 1.5E+08 0E+00 10 100 1000 10000 100000 Elementos
    37. 37. SPLHeap 100 19 36 17 3 25 1 2 7
    38. 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)
    39. 39. abstract SplHeap implements Iterator, Countable { /* Methods */ __construct ( void ) abstract int compare ( mixed $value1 , mixed $value2 ) int count ( void ) mixed current ( void ) mixed extract ( void ) void insert ( mixed $value ) bool isEmpty ( void ) mixed key ( void ) void next ( void ) void recoverFromCorruption ( void ) void rewind ( void ) mixed top ( void ) bool valid ( void ) }
    40. 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. 41. SPLMaxHeap Cada nodo é menor do que ou igual ao nodo pai, de acordo com algum critério de comparação
    42. 42. Benchmark #5 $array = array(); for($i = 0; $i < $argv[1]; $i++) { $array[] = rand(1, $argv[1]); rsort($a); } for($i = 0; $i < $argv[1]; $i++) { array_shift($array); }
    43. 43. Benchmark #5 $heap = new SPLMaxHeap; for($i = 0; $i < $argv[1]; $i++) { $heap->insert(rand(1, $argv[1])); } for($i = 0; $i < $argv[1]; $i++) { $heap->extract(); }
    44. 44. Benchmark #5 Elementos Array (μs) SPLMaxHeap (μs) Razão 10 83 88 0.94 100 1626 831 1.96 1000 157319 8431 18.66 10000 21423280 95029 225.44
    45. 45. Benchmark #5 Array SPLMaxHeap 30000000 22500000 Tempo (μs) 15000000 7500000 0 10 100 1000 10000 Elementos
    46. 46. SPLMinHeap Cada nodo é maior do que ou igual ao nodo pai, de acordo com algum critério de comparação
    47. 47. Benchmark #6 $array = array(); for($i = 0; $i < $argv[1]; $i++) { $array[] = rand(1, $argv[1]); sort($a); } for($i = 0; $i < $argv[1]; $i++) { array_shift($array); }
    48. 48. Benchmark #6 $heap = new SPLMinHeap; for($i = 0; $i < $argv[1]; $i++) { $heap->insert(rand(1, $argv[1])); } for($i = 0; $i < $argv[1]; $i++) { $heap->extract(); }
    49. 49. Benchmark #6 Elementos Array (μs) SPLMinHeap (μs) Razão 10 82 88 0.93 100 1575 830 1.90 1000 156638 9054 17.30 10000 18821974 90559 207.84
    50. 50. Benchmark #5 Array SPLMinHeap 20000000 15000000 Tempo (μs) 10000000 5000000 0 10 100 1000 10000 Elementos
    51. 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. 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; } }
    53. 53. SPLHeap $campeonato = new Campeonato; $campeonato->insert($time1); $campeonato->insert($time2); $campeonato->insert($time3); while($campeonato->valid()) { $time = $campeonato->current(); echo $time->nome ." - ". $time->pontos . "ptsn"; $campeonato->next(); }
    54. 54. SPLPriorityQueue Fila de prioridade
    55. 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
    56. 56. SplPriorityQueue implements Iterator, Countable { /* Methods */ __construct ( void ) void compare ( mixed $priority1 , mixed $priority2 ) int count ( void ) mixed current ( void ) mixed extract ( void ) void insert ( mixed $value , mixed $priority ) bool isEmpty ( void ) mixed key ( void ) void next ( void ) void recoverFromCorruption ( void ) void rewind ( void ) void setExtractFlags ( int $flags ) mixed top ( void ) bool valid ( void ) }
    57. 57. SPLPriorityQueue $fila = new SPLPriorityQueue; $fila->insert("adulto",1); $fila->insert("gestante",2); $fila->insert("deficiente",2); $fila->insert("idoso",3); while($fila->valid()) { echo "Próximo: ".$fila->extract()."n"; } //Próximo: idoso //Próximo: gestante //Próximo: deficiente //Próximo: adulto
    58. 58. SPLObjectStorage Funciona como um Set ou um mapa
    59. 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. 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. 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. 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]); }
    63. 63. <?php echo "Dúvidas?"; $card = array( 'nome' => 'Felipe Ribeiro', 'site' => 'http://feliperibeiro.com', 'e-mail' => 'felipernb@php.net', 'twitter' => '@felipernb', 'fone' => '(83) 9979-3161' ); var_dump($card); ?>

    ×