SlideShare uma empresa Scribd logo
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);
?>

Mais conteúdo relacionado

PDF
Java script aula 04 - objeto array
PDF
Proxy, Man-In-The-Middle e testes
PPTX
Capítulo 6
PDF
Perl Moderno, dia3
PDF
Object Calisthenics: relaxe e escreva códigos simples
PDF
PHP para Adultos: Clean Code e Object Calisthenics
PDF
LabMM4 (T14 - 12/13) - Arrays
PDF
Perl Moderno, dia5
Java script aula 04 - objeto array
Proxy, Man-In-The-Middle e testes
Capítulo 6
Perl Moderno, dia3
Object Calisthenics: relaxe e escreva códigos simples
PHP para Adultos: Clean Code e Object Calisthenics
LabMM4 (T14 - 12/13) - Arrays
Perl Moderno, dia5

Mais procurados (20)

PDF
Perl Moderno, dia2
ODP
meetup adopting java8
PDF
Da Argila Ao Forte - Como desenvolver uma loja virtual
PDF
Perl Moderno, dia4
PPTX
NotORM
PDF
Perl Moderno, dia1
KEY
PHPubSP Object Calisthenics aplicado ao PHP
PDF
LabMM3 - Aula teórica 10
PDF
Introdução a ciência de dados com Python
PPT
LINQ - Language Integrated Query
PDF
Resolução lista2
PDF
PHP MySQL Aula 07
PDF
LabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveis
PPTX
PPTX
PHP Básico - Parte 3
ODP
TDC2016POA | Trilha Java - Atualizando para Java 8 na prática!
PDF
Crawling - Coleta de dados na Web com PHP
PPTX
Otimização e Escalabilidade
PPT
Bd sql (1)
PDF
Java 8 - Afinal onde usamos no dia a dia? TDC 2015 - Porto Alegre
Perl Moderno, dia2
meetup adopting java8
Da Argila Ao Forte - Como desenvolver uma loja virtual
Perl Moderno, dia4
NotORM
Perl Moderno, dia1
PHPubSP Object Calisthenics aplicado ao PHP
LabMM3 - Aula teórica 10
Introdução a ciência de dados com Python
LINQ - Language Integrated Query
Resolução lista2
PHP MySQL Aula 07
LabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveis
PHP Básico - Parte 3
TDC2016POA | Trilha Java - Atualizando para Java 8 na prática!
Crawling - Coleta de dados na Web com PHP
Otimização e Escalabilidade
Bd sql (1)
Java 8 - Afinal onde usamos no dia a dia? TDC 2015 - Porto Alegre
Anúncio

Destaque (20)

PDF
Validação e Operações CRUD em PHP
PDF
PHP 5.3 - What's new?
KEY
PHP RESTful Web Services - PHPConf'09
PPTX
TDC POA 2016 - Priorizando sem trauma
PDF
7Masters jQuery - Acessibilidade com jQuery Validate, com Deivid Marques
PDF
7Masters jQuery - jQuery além do código, com Leon Kulikowski
PDF
#NoEndState : Plataformas, Produtores e Interfaces no Product tank meetup
PDF
Os Caminhos do Design Mobile - Campus Party 2013
PDF
QConSP16 - Apache Cassandra Evoluindo Sistemas Distribuídos
PDF
PHP for Adults: Clean Code and Object Calisthenics
PPT
Como lidar com dados temporais e intervalos com a linguagem SQL
PPTX
CNQS - Testes Automatizados & Continuous Delivery
PDF
Let's log!
PDF
Como o ViajaNet aumentou suas vendas com SEO
PDF
PDF
7Masters jQuery - Eventos em jQuery, com Felquis Gimenes
PDF
Twitter: 10 anos de existência
PPTX
Cost Effective Data-Based Content Marketing
KEY
Advanced Django Forms Usage
PDF
As Media Queries são só um detalhe!
Validação e Operações CRUD em PHP
PHP 5.3 - What's new?
PHP RESTful Web Services - PHPConf'09
TDC POA 2016 - Priorizando sem trauma
7Masters jQuery - Acessibilidade com jQuery Validate, com Deivid Marques
7Masters jQuery - jQuery além do código, com Leon Kulikowski
#NoEndState : Plataformas, Produtores e Interfaces no Product tank meetup
Os Caminhos do Design Mobile - Campus Party 2013
QConSP16 - Apache Cassandra Evoluindo Sistemas Distribuídos
PHP for Adults: Clean Code and Object Calisthenics
Como lidar com dados temporais e intervalos com a linguagem SQL
CNQS - Testes Automatizados & Continuous Delivery
Let's log!
Como o ViajaNet aumentou suas vendas com SEO
7Masters jQuery - Eventos em jQuery, com Felquis Gimenes
Twitter: 10 anos de existência
Cost Effective Data-Based Content Marketing
Advanced Django Forms Usage
As Media Queries são só um detalhe!
Anúncio

Semelhante a SPL Datastructures (20)

PDF
PHP 5.3 - Arrays
PDF
Por que dizemos que Scala é uma linguagem funcional?
PDF
Aquece Para a prova de EDA3
PPT
Php
PDF
Ruby e Erlang de mãos dadas
PPTX
Aula 02 - Curso PHP e MySQL
PDF
O que mudou no Ruby 1.9
PDF
PW03 - Programação Web PHP Arrays (Vetores)
PDF
Manual_Dicas e truques de script - MikroTik Wiki.pdf
PPTX
PHP Conference 2017: Como melhorar seu código com Laravel Collections
ODP
Linguagem R
PDF
Curso de PHP - Arrays
PDF
Apostila php 01
PDF
4234 mysql
PPTX
Arrays PHP - Criação de sites II
PPTX
Aula sobre Arrays e objetos em PHP para iniciantes
PPTX
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
PPT
Trabalho vetores
PDF
Iteraveis e geradores
PHP 5.3 - Arrays
Por que dizemos que Scala é uma linguagem funcional?
Aquece Para a prova de EDA3
Php
Ruby e Erlang de mãos dadas
Aula 02 - Curso PHP e MySQL
O que mudou no Ruby 1.9
PW03 - Programação Web PHP Arrays (Vetores)
Manual_Dicas e truques de script - MikroTik Wiki.pdf
PHP Conference 2017: Como melhorar seu código com Laravel Collections
Linguagem R
Curso de PHP - Arrays
Apostila php 01
4234 mysql
Arrays PHP - Criação de sites II
Aula sobre Arrays e objetos em PHP para iniciantes
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
Trabalho vetores
Iteraveis e geradores

Último (19)

PDF
Mergulho profundo técnico para gestão de transportes no SAP S/4HANA, S4TM6 Col14
PPTX
Programação - Linguagem C - Variáveis, Palavras Reservadas, tipos de dados, c...
PPTX
Como-se-implementa-um-softwareeeeeeeeeeeeeeeeeeeeeeeee.pptx
PDF
Fullfilment AI - Forum ecommerce 2025 // Distrito e Total Express
PPTX
Gestao-de-Bugs-em-Software-Introducao.pptxxxxxxxx
PDF
Otimizador de planejamento e execução no SAP Transportation Management, TM120...
PDF
Aula04-Academia Heri- Tecnologia Geral 2025
PDF
Fundamentos de gerenciamento de ordens e planejamento no SAP TransportationMa...
PDF
20250805_ServiceNow e a Arquitetura Orientada a Serviços (SOA) A Base para Ap...
PDF
Custos e liquidação no SAP Transportation Management, TM130 Col18
PDF
Apple Pippin Uma breve introdução. - David Glotz
PDF
Custos e faturamento no SAP S/4HANA Transportation Management, S4TM3 Col26
PPTX
Aula16ManipulaçãoDadosssssssssssssssssssssssssssss
PDF
COBITxITIL-Entenda as diferença em uso governança TI
PPTX
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
PDF
Gestão de transportes básica no SAP S/4HANA, S4611 Col20
PPTX
Aula 18 - Manipulacao De Arquivos python
PPTX
BANCO DE DADOS - AULAS INICIAIS-sgbd.pptx
PDF
Processos na gestão de transportes, TM100 Col18
Mergulho profundo técnico para gestão de transportes no SAP S/4HANA, S4TM6 Col14
Programação - Linguagem C - Variáveis, Palavras Reservadas, tipos de dados, c...
Como-se-implementa-um-softwareeeeeeeeeeeeeeeeeeeeeeeee.pptx
Fullfilment AI - Forum ecommerce 2025 // Distrito e Total Express
Gestao-de-Bugs-em-Software-Introducao.pptxxxxxxxx
Otimizador de planejamento e execução no SAP Transportation Management, TM120...
Aula04-Academia Heri- Tecnologia Geral 2025
Fundamentos de gerenciamento de ordens e planejamento no SAP TransportationMa...
20250805_ServiceNow e a Arquitetura Orientada a Serviços (SOA) A Base para Ap...
Custos e liquidação no SAP Transportation Management, TM130 Col18
Apple Pippin Uma breve introdução. - David Glotz
Custos e faturamento no SAP S/4HANA Transportation Management, S4TM3 Col26
Aula16ManipulaçãoDadosssssssssssssssssssssssssssss
COBITxITIL-Entenda as diferença em uso governança TI
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
Gestão de transportes básica no SAP S/4HANA, S4611 Col20
Aula 18 - Manipulacao De Arquivos python
BANCO DE DADOS - AULAS INICIAIS-sgbd.pptx
Processos na gestão de transportes, TM100 Col18

SPL Datastructures

  • 1. SPL Datastructures Estruturas de dados e algoritmos em PHP Felipe Ribeiro http://feliperibeiro.com felipernb@php.net @felipernb
  • 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
  • 5. Estruturas de dados Armazenamento Organização Conjuntos
  • 6. PHP 5.3 traz SPL Datastrucutres
  • 7. O bom e velho Array não era suficiente?
  • 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. <?php $array = array(); $array[0] = "foo"; $array['bar'] = "baz"; $array[525] = "xpto"; echo $array[0]; ?>
  • 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'
  • 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. 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()
  • 22. SPLStack LIFO (Last In, First Out) Duas operações Push (Empilha) Pop (Desempilha)
  • 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. 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. 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. 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. 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. 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. Benchmark #3 Array SPLStack 60000 45000 Tempo (μs) 30000 15000 0 10 100 1000 10000 Elementos
  • 31. SPLQueue FIFO (First In, First Out) Duas operações: Enqueue (enfileirar) Dequeue (desenfileirar)
  • 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. Benchmark #4 $array = array(); for($i = 0; $i < $argv[1]; $i++) { $array[] = $i; } for($i = 0; $i < $argv[1]; $i++) { array_shift($array); }
  • 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. 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. 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. SPLHeap 100 19 36 17 3 25 1 2 7
  • 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. 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. 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
  • 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. 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. 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. Benchmark #5 Array SPLMaxHeap 30000000 22500000 Tempo (μs) 15000000 7500000 0 10 100 1000 10000 Elementos
  • 46. SPLMinHeap Cada nodo é maior do que ou igual ao nodo pai, de acordo com algum critério de comparação
  • 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. 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. 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. 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; } }
  • 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(); }
  • 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. 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. 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
  • 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]); }
  • 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); ?>