Existem métodos que servem apenas para retornar arrays. Em alguns casos, estes arrays são muito grandes e ocupam muito espaço no próprio arquivo da classe onde o método se encontra. Arquivos muito grandes acarretam em uso de memória para carregá-los. Por este motivo pode ser útil considerar uma estratégia de otimização deste array, para que ele só seja carregado caso necessário (consulta sob demanda).
A alternativa simples é criar um outro arquivo PHP que apenas cria um array chamado $array, por exemplo, e este arquivo é incluído pelo método que retorna o array. Desta forma, o arquivo original (que tem o método) fica enchuto e o array só é carregado quando o método é invocado. Veja, abaixo, um exemplo de como era a classe antes e como ela ficou depois.
Antes:
<?php // Arquivo teste.class.php class teste { // Funcao que retorna um array grande public static function get_tipos() { return array( 1 => 'Abacate', 2 => 'Abacaxi', 3 => 'Amora', ... 100000 => 'Banana', 100001 => 'Maçã', 100002 => 'Pêra' ); } // Outros metodos da classe "teste" ... }
Depois:
<?php // Arquivo teste.class.php class teste { // Funcao que retorna um array grande public static function get_tipos() { include(dirname(__FILE__).'/array.php'); return $array; } // Outros metodos da classe "teste" ... }
<?php // Arquivo array.php $array = array( 1 => 'Abacate', 2 => 'Abacaxi', 3 => 'Amora', ... 100000 => 'Banana', 100001 => 'Maçã', 100002 => 'Pêra' );
Uma solução híbrida, é criar um array estático dentro do método e preenchê-lo sob demanda. Desta forma, o array será carregado apenas na primeira vez que o método é executado e, nas demais, ele é apenas retornado. Veja o exemplo:
<?php // Arquivo teste.class.php class teste { // Funcao que retorna um array grande public static function get_tipos() { static $array = null; if ($array === null) { include(dirname(__FILE__).'/array.php'); } return $array; } // Outros metodos da classe "teste" ... }
Fazendo um teste com um array de 1000 posições com valores aleatórios, obtive o seguinte resultado:
Chamadas ao método get_array | Script | Tempo (segundos) | Memória (bytes) |
---|---|---|---|
0 | não otimizado | 0.00270 | 429.336 |
otimizado | 0.00023 | 332.052 | |
híbrido | 0.00024 | 332.324 | |
1 | não otimizado | 0.00385 | 514784 |
otimizado | 0.00392 | 516.220 | |
híbrido | 0.00435 | 516.464 | |
1000 | não otimizado | 0.20694 | 611.356 |
otimizado | 1.11245 | 630.140 | |
híbrido | 0.14143 | 536.780 |
Ou seja, quando o método não é utilizado, o carregamento da classe otimizada e da classe híbrida é muito mais rápido que a classe não otimizada. Quando o método é utilizado uma única vez, as três classes têm performance muito próxima. Entretanto, quando o método é utilizado muitas vezes, a classe otimizada demora muito mais tempo para carregar o array, já a classe não otimizada e a classe híbrida obtem uma boa performance.
Portanto, leve em consideração a quantidade de vezes que o método será invocado em uma execução.
Note que a mesma ideia também vale para biblioteca de funções. Caso uma função retorne um array muito grande, você pode separar o array em outro arquivo.
2 comentários
como voce faz para obter esses resultados de performance? é algum benchmark ou alguma artimanha com o proprio php?
É utilizando recursos do próprio PHP.
Para obter o tempo gasto, utilizei a função microtime.
Para obter a quantidade de memória, usei memory_get_usage.
Executei um script de teste algumas vezes e obtive a média (que é o valor apresentado).
Postar um comentário
Nota: fique a vontade para expressar o que achou deste artigo ou do blog.
Dica: para acompanhar as respostas, acesse com uma conta do Google e marque a opção "Notifique-me".
Atenção: o blogger não permite inclusão de tags nos comentários, por isso, use algum site externo para postar seu código com dúvidas e deixe o link aqui. Exemplo: pastebin.com