Este post não é sobre CakePHP diretamente, mas pode influenciar no modo de programarmos no cake.
Olhando alguns sites de otimização, benchmark, entre outros, vi que há algumas formas de otimizarmos os códigos sem grandes alterações, mas que podem melhorar a performance. São elas:
1) Aspas com variáveis
1.1) Aspas duplas VS aspas simples
Utilizar uma string com aspas simples é ligeiramente mais rápido que utilizar aspas duplas pelo fato da necessidade de interpretar varáveis (com aspas simples ele interpreta variáveis). Exemplo:
1
2
| echo 'texto qualquer'; // Mais rápido
echo "texto qualquer"; // Mais lento |
1.2) Variável em aspas dupla ou concatenando
Concatenar uma variável a uma string é muito mais rápido que colocar a variável dentro de uma string com aspas duplas.
1
2
| echo 'texto qualquer ' . $variavel . ' outro texto'; // Quase duas vezes mais rápido
echo "texto qualquer $variavel outro texto"; // Bem mais lento |
2) echo VS print
Utilizar a função echo é mais rápida que a função print, pois não retorna nenhum valor. A função print informa se houve mensagem de erro. O uso de print é recomendado só em casos que há necessidade de retorno (o que são poucos na prática). Além disso, é recomendável a utilização vários parâmetros no echo ao invés de concatenar strings. É opcional o uso de parâmetros nestes comandos, sendo o ideal não utilizar. Exemplo:
1
2
3
| echo 'texto qualquer ' . $variavel . ' outro texto';
print 'texto qualquer ' . $variavel . ' outro texto'; // Mais lento que caso anterior
echo 'texto qualquer ', $variavel, ' outro texto'; // Note as vírgulas. Este caso é mais rápido que os anteriores |
3) Variáveis
3.1) Nomes
Definir variáveis com nomes menores é consideravelmente mais rápido que nome maiores. Exemplo:
1
2
| $a = 'texto';
$asdhaisuhniduahsduiash = 'a'; // Mais lento que anteiror, consideravelmente |
3.2) Atribuições
Em atribuições, várias atribuições são mais rápidas que em atribuições unificadas. Exemplo:
1
2
| $a=$b=0; // Mais lento
$a=0; $b=0; // Mais rápido |
Usar os operadores +=, -=, /=, *= e .= também aumentam a performance. Exemplo:
1
2
3
4
5
6
7
| $var = 'abc';
// Mais lento
$var = $var . 'def';
// Mais rápido
$var .= 'def'; |
3.3) [Pré/Pós]-incremento
Preferir o uso de pré-incremento (++$i) ao invés de pós-incremento ($i++), pois aquelas consumem um opcode a menos, visto que o segundo caso o PHP cria uma variável temporária para atribuir o valor e no primeiro caso não. PS: Isto vale apenas para PHP! Nas outras linguagens isto não se aplica.
4) Estruturas condicionais
4.1) if VS switch
Estruturas com if e vários elseif são mais rápidas que a estrutura switch. Exemplo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| // Mais rápido
if ($a == 1) {
echo 1;
} elseif ($a == 2) {
echo 2;
} else {
echo 3;
}
// Mais lento
switch ($a) {
case 1:
echo 1;
break;
case 2:
echo 2;
break;
default:
echo 3;
} |
4.2) Operador ternário VS if
Operadores ternários são significativamente mais lentos que if’s. Exemplo:
1
2
3
4
5
6
7
8
9
| // Mais lento
echo $a == 1 ? 1 : 2;
// Mais rápido
if ($a == 1) {
echo 1;
} else {
echo 2;
} |
4.3) Operadores de igualdade
Operadores de igualdade com comparação de tipos (===) são consideravelmente mais rápidos que apenas operadores de igualdade (==). Exemplo:
1
2
| if ($a == 'a') { // Mais lento
if ($a === 'a') { // Mais rápido |
5) Arrays
5.1) Definição
Definir um array pelos índices é consideravelmente mais rápido que usar o método array(…). Exemplo:
1
2
| $a = array('a', 'b'); // Mais lento
$a[0] = 'a'; $a[1] = 'b'; // Mais rápido |
5.2) Leitura
Verificar a existência de um elemento no array é mais rápido que procurá-lo. Exemplo:
1
2
| in_array('texto', $arr); // Mais lento
isset($arr['texto']); // Mais rápido |
6) Arquivos
Usar a função file_get_contents() é ligeiramente mais rápida que utilizar a função file(), porém é mais lenta que utilizar fopen() com fread(). Exemplo:
1
2
3
4
5
6
7
8
9
10
| // Mais lento
$arquivo = file('arquivo.txt'); // Retorna array
// Pouco mais rápido que anterior
$arquivo = file_get_contents('arquivo.txt'); // Retorna string
// Mais rápido, significativamente
$f = fopen('arquivo.txt', 'r');
$arquivo = fread($f, filesize('arquivo.txt'));
fclose($f); |
7) Buscas e validações
7.1) Substring
Ao buscar substrings, é preferível usar, na ordem, strpos(), depois preg_match() e por último ereg(). A strpos, quando é possível de ser utilizada, tem uma eficiência muito superior as demais.
7.2) Números
Caso necessite verificar se um texto ou variável contém apenas números, é preferivel utilizar a função ctype_digit($var) ao invés de preg_match(’/[0-9]*/’, $var).
8 ) Outras otimizações
8.1) Funções de controle de saída
Uso de Usar o método ob_start() reduz de 5 a 15% o tempo de execução.
8.2) Evitando repetição de funções
Definir uma variável com um valor que vai ser usado diversas vezes aumenta a performance consideravalmente. Exemplo:
1
2
| for ($i=0, $max=count($arr); $i<$max; $i++) { // Mais rápido
for ($i=0; $i<count($arr); $i++) { // Mais lento |
8.3) Processamento não necessário
Blocos de textos fixos é preferível que seja impresso fora do PHP, por exemplo:
1
2
| <?php echo $var; ?>
Texto adicional grande |
É preferível do que:
1
| <?php echo $var . 'Texto adicional grande'; ?> |
8.4) Evitar o uso de funções aliases e automágicas
Funções aliases são as funções que significam a mesma coisa que outras. Por exemplo, sizeof é sinônimo (alias) de count. Veja a lista completa de funções aliases aqui.
Funções automágicas são aquelas definidas pelo PHP: __get, __set, __autoload, __call, __sleep, …
8.5) Evitar uso de funções abrangentes
Preferir a função empty() ao invés de count(), assim como isset($var{X}) ao invés de strlen($var) < X.
8.6) Declare os métodos estáticos
Definir os métodos estáticos com a palavra static deixa seu código até 4 vezes mais rápido que o não declarado como estático. Exemplo:
1
2
3
4
5
6
7
| class XXX {
public function a() { return 1; }
public static fuction b() { return 1; }
}
XXX::a(); // Mais lento
XXX::b(); // Até 4 vezes mais rápido |
8.7) Evitar o operador @
Ao invés de usar o operador @, desativar a exibição de erros. Exemplo:
1
2
3
4
5
6
7
| // Mais lento
@acao();
// Mais rápido
$old = ini_set('error_reporting', 0);
acao();
ini_set('error_reporting', $old); |
9) Extra-código
Se você tem acesso ao servidor web, é recomendavel a utilização de otimizadores e/ou cachers, como o Zend Optimizer, APC, eAccelerator, memcache, etc.
Outra alternativa que pode ser usada em conjunto, é usar o callback ‘ob_gzhandler‘ na função ob_start() OU ativar a configuração zlib.output_compression no php.ini. Isso faz com que depois de gerado o código HTML, ele seja compactado e enviado para o cliente, reduzindo a quantidade de tráfego na rede.
Fontes de referência:
https://trac.cakephp.org/ticket/2764
http://phplens.com/lens/php-book/optimizing-debugging-php.php
http://benchmark.nophia.de/benchmarks.html
http://www.estvideo.com/dew/pages/phpbench/
http://ilia.ws/archives/12-PHP-Optimization-Tricks.html
http://www.vulgarisation-informatique.com/optimiser-php.php
http://www.moskalyuk.com/blog/php-optimization-tips/1272
http://www.ilia.ws/files/zend_performance.pdf
http://www.faqts.com/knowledge_base/view.phtml/aid/1/fid/40