• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
SPL Datastructures
 

SPL Datastructures

on

  • 6,827 views

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

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

Statistics

Views

Total Views
6,827
Views on SlideShare
4,193
Embed Views
2,634

Actions

Likes
21
Downloads
137
Comments
1

9 Embeds 2,634

http://blog.feliperibeiro.com 2084
http://phpsp.org.br 461
http://old.feliperibeiro.com 59
http://www.slideshare.net 14
http://feedly.com 8
http://rtiweb.net 3
http://webcache.googleusercontent.com 2
http://translate.googleusercontent.com 2
http://www.linkedin.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Estou começando o estudo de PHP. Porém o conteudo parece mostrar novas funcionalidades do php 5.3 de uma forma simples.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

SPL Datastructures SPL Datastructures Presentation Transcript

  • SPL Datastructures Estruturas de dados e algoritmos em PHP Felipe Ribeiro http://feliperibeiro.com felipernb@php.net @felipernb
  • 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
  • SPL Classes e interfaces nativas
  • Estruturas de dados
  • Estruturas de dados Armazenamento Organização Conjuntos
  • PHP 5.3 traz SPL Datastrucutres
  • O bom e velho Array não era suficiente?
  • 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
  • <?php $array = array(); $array[0] = "foo"; $array['bar'] = "baz"; $array[525] = "xpto"; echo $array[0]; ?>
  • 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()
  • 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 ) }
  • $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'
  • 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; }
  • 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
  • Benchmark #1 (criando e preenchendo um novo Array) Array SPLFixedArray 100000 75000 Tempo (μs) 50000 25000 0 10 100 1000 10000 100000 Elementos
  • 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)]; } }
  • 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
  • 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
  • SPLDoublyLinkedList cabeça cauda
  • 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()
  • SPLStack Pilha
  • SPLStack LIFO (Last In, First Out) Duas operações Push (Empilha) Pop (Desempilha)
  • 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!
  • 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)
  • 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)
  • 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); }
  • Benchmark #3 $stack = new SPLStack(); for($i = 0; $i < $argv[1]; $i++ ) { $stack->push($i); } for($i = 0; $i < $argv[1]; $i++) { $stack->pop(); }
  • 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
  • Benchmark #3 Array SPLStack 60000 45000 Tempo (μs) 30000 15000 0 10 100 1000 10000 Elementos
  • SPLQueue Fila
  • SPLQueue FIFO (First In, First Out) Duas operações: Enqueue (enfileirar) Dequeue (desenfileirar)
  • 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!
  • Benchmark #4 $array = array(); for($i = 0; $i < $argv[1]; $i++) { $array[] = $i; } for($i = 0; $i < $argv[1]; $i++) { array_shift($array); }
  • Benchmark #4 $queue = new SPLQueue; for($i = 0; $i < $argv[1]; $i++) { $queue[] =$i; } for($i = 0; $i < $argv[1]; $i++) { $queue->dequeue(); }
  • 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
  • Benchmark #4 Array SPLQueue 6E+08 4.5E+08 Tempo (μs) 3E+08 1.5E+08 0E+00 10 100 1000 10000 100000 Elementos
  • SPLHeap 100 19 36 17 3 25 1 2 7
  • 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)
  • 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 ) }
  • 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); }
  • SPLMaxHeap Cada nodo é menor do que ou igual ao nodo pai, de acordo com algum critério de comparação
  • 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); }
  • 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(); }
  • 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
  • Benchmark #5 Array SPLMaxHeap 30000000 22500000 Tempo (μs) 15000000 7500000 0 10 100 1000 10000 Elementos
  • SPLMinHeap Cada nodo é maior do que ou igual ao nodo pai, de acordo com algum critério de comparação
  • 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); }
  • 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(); }
  • 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
  • Benchmark #5 Array SPLMinHeap 20000000 15000000 Tempo (μs) 10000000 5000000 0 10 100 1000 10000 Elementos
  • 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
  • SPLHeap class Campeonato extends SPLHeap { public function compare($time1, $time2) { if($time1->pontos == $time2->pontos) return 0; return $time1->pontos < $time2->pontos? -1:1; } }
  • 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(); }
  • SPLPriorityQueue Fila de prioridade
  • 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
  • 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 ) }
  • 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
  • SPLObjectStorage Funciona como um Set ou um mapa
  • 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
  • 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 ) }
  • // 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)
  • // 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]); }
  • <?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); ?>