Otimização de arrays desnecessários em PHP
Suponha que um programador tenha a tarefa
de encontrar a soma dos números inteiros de 1 a 100000000.
Nosso programador escreveu uma solução elegante para este problema, assim:
<?php
echo array_sum(range(1, 100000000));
?>
Solução bonita, não é? Em uma linha e tudo mais. Mas não funciona! Tente executar este código e ele exibirá um erro sobre o fato de você ter solicitado muita memória RAM.
Hmm, 100000000 não parece muito?
Ou é muito? Vamos calcular. A função range
cria um array com 100000000 números.
Suponha que o PHP aloque 2 bytes
por número - então, para armazenar nosso array, seriam necessários
200000000 bytes, ou seja, cerca de
200 megabytes de memória RAM.
Mas, na verdade, será necessária muito mais
memória RAM devido às altas
despesas gerais (overhead) no PHP para armazenar um array.
Por exemplo, no meu texto, o erro informa
que estou tentando alocar 4294967304
bytes - cerca de 4 gigabytes!
Agora está claro por que o erro ocorre - excedemos em muito o limite de memória permitido.
Não é difícil reescrever nosso script de outra forma, que praticamente não consome memória RAM:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Ou, melhor ainda, usamos a solução matemática:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Um programador tinha a tarefa de encontrar o fatorial de um determinado número. Ele resolveu da seguinte forma:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Explique o que há de errado com este código. Reescreva o código de forma mais otimizada.
Um programador tinha a tarefa de encontrar
a quantidade de dígitos necessários para
escrever todos os números inteiros de 1 a 1000000.
Ele resolveu da seguinte forma:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Explique o que há de errado com este código. Reescreva o código de forma mais otimizada.
Um programador tinha a tarefa de encontrar
a quantidade de números divisíveis
por 7, em um determinado
intervalo. Ele resolveu da seguinte forma:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Explique o que há de errado com este código. Reescreva o código de forma mais otimizada.
Um programador tinha a tarefa de encontrar a soma dos divisores de um número. Ele resolveu da seguinte forma:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Explique o que há de errado com este código. Reescreva o código de forma mais otimizada.