Desemepnho de aplicações é cada vez mais importante. A Web está mais cheia de conteúdo a cada dia. E, consequentemente, as páginas tendem a possuir mais dados. Se não tomarmos cuidado com o desempenho, nossos sistemas ficarão lentos.
Uma forma de contornar esse problema é fazer cache de dados usados com frequência. Há várias maneiras de fazer cache com PHP. Neste artigo, vou falar do APC (Alternative PHP Cache), que é uma extensão do próprio PHP muito simples de usar.
O Que é Cache?
Segundo a Wikipedia, cache é “um dispositivo de acesso rápido, interno a um sistema, que serve de intermediário entre um operador de um processo e o dispositivo de armazenamento ao qual esse operador acede”. Ou seja, cache é um local de rápido acesso a informações que ficam salvas em um dispositovo cujo acesso é mais lento.
Por exemplo, um arquivo em disco pode ter seu conteúdo armazenado em cache na memória. O tempo de acesso à memória é muito mais rápido que o de acesso ao disco. Por isso é útil fazer cache em memória de arquivos acessados frequentemente.
O Que é o APC?
APC (Alternative PHP Cache) é uma extensão do PHP. Ela faz cache de dados em memória. Basta dizer qual será a “chave” (um identificador único para o dado salvo), qual é a informação a ser salva e por quanto tempo ela deve ser mantida em cache. O resto é tarefa do PHP.
A extensão APC não vem habilitada por padrão. É necessário habilitá-la em seu php.ini, ou instalar o pacote correspondente, caso tenha instalado o PHP a partir dos pacotes para Linux ou Mac OS X.
Como Usar o APC Para Fazer Cache com PHP
Existem algumas funções do APC, mas vou me ater às seguintes:
apc_add
: adiciona um dado ao cache, caso ainda não esteja salvo;apc_clear_cache
: limpa o cache do APC;apc_delete
: remove um valor do cache;apc_exists
: verifica se uma determinada chave existe no cache;apc_fetch
: retorna um valor salvo no cache;apc_store
: salva um valor no cache, sobrescrevendo-o, caso já exista.
Adicionando um Valor ao Cache
Para adicionar um valor ao cache, é possível usar apc_add
ou apc_store
. A única diferença entre essas duas funções é que apc_add adiciona um dado ao cache apenas se ele ainda não existir. Já apc_store sempre adiciona o dado. Consequentemente, apc_store vai sobrescrever a informação, caso ela já tenha sido armazenada anteriormente.
A sintaxe de ambas as funções é a mesma, desta forma:
bool apc_add ( string $key , mixed $var [, int $ttl ] ) bool apc_store ( string $key , mixed $var [, int $ttl ] ) |
O parâmetro $key
é a chave de identificação para a informação no cache. É esse valor que usaremos para buscar ou remover o dado do cache. O parâmetro $var
é o valor a ser armazenado no cache. Ele pode ser uma simples variável, um array ou mesmo um objeto. E o parâmetro $ttl
(Time To Live) é o tempo, em segundos, que o dado deve permanecer em cache. Se $ttl
não for especificado (ou for 0
), o dado será mantido em cache até que seja manualmente removido.
Para exemplificar, vamos inserir alguns dados no cache, todos com tempo de vida de 60 segundos:
$a = 'valor a'; apc_add( 'chave_a', $a, 60 ); $arr = [ 'a' => 1, 'b' => 2 ]; apc_add( 'meu_array', $arr, 60 ); $obj = new stdClass; $obj->nome = 'Beraldo'; apc_add( 'meu_objeto', $obj, 60 ); |
Retornando Dados Salvos no Cache
Para retornar um dado salvo no cache, usamos a função apc_fetch
. Basta passar como parâmetro a chave que utilizamos em apc_add
ou em apc_store
.
$a = apc_fetch( 'chave_a' ); var_dump( $a ); $arr = apc_fetch( 'meu_array' ); var_dump( $arr ); $obj = apc_fetch( 'meu_objeto' ); var_dump( $obj ); |
Se os dados estiverem em cache, var_dump
os exibirá. Caso contrário, será retornado FALSE.
Verificando a Existência de um Dado no Cache
Antes de retornar o dado com apc_fetch
, podemos usar apc_exists
para verificar se a chave existe no cache. Assim, podemos alterar o trecho anterior pelo seguinte.
if ( apc_exists( 'chave_a' ) ) { $a = apc_fetch( 'chave_a' ); var_dump( $a ); } else { echo "Chave chave_a não está no cache"; } if ( apc_exists( 'meu_array' ) ) { $arr = apc_fetch( 'meu_array' ); var_dump( $arr ); } else { echo "Chave meu_array não está no cache"; } if ( apc_exists( 'meu_objeto' ) ) { $obj = apc_fetch( 'meu_objeto' ); var_dump( $obj ); } else { echo "Chave meu_objeto não está no cache"; } |
Removendo Um Dado do Cache
Para remover um dado específico, usamos apc_delete
.Basta passar a chave por parâmetro, desta forma:
apc_delete( 'chave_a' ); apc_delete( 'meu_array' ); apc_delete( 'meu_objeto' ); |
Limpando Todo o Cache
Para limpar o cache completamente, basta usar a função apc_clear_cache
:
apc_clear_cache(); |
Dessa forma, todos os dados salvos em cache serão apagados.
Comparando Desempenho
Para mostrar a diferença de tempo entre acessar um dado em disco e outro dado em cache, vou mostrar uma comparação de desempenho entre ambos.
Para isso, usarei um arquivo .ini
, que é geralmente utilizado para armazenar configurações do sistema. Caso você não saiba trabalhar com arquivos .ini
usando o PHP, recomendo que leia este meu post, onde mostro como fazer isso.
Critério de Avaliação
Para avaliar o desempenho, usarei apenas o tempo de execução da tarefa em questão. Usarei a função microtime
, que retorna a hora atual, em microssegundos. Tendo a hora de início e a hora de término, basta subtraí-las e teremos o tempo de execução total. Vou considerar apenas o tempo de acesso ao dispositivo (disco e cache), sem considerar o tempo para exibir o dado na tela. Para exibir o resultado, usarei number_format
, pois, quando o tempo é muito pequeno, o número é exibido em notação científica (no formato 5.124E-10) e pode confundir quem não está habituado a visualizar números nesse formato.
Arquivo de Configuração
Primeiramente, crie um arquivo chamado config.ini
, com o seguinte conteúdo:
[db] host = "localhost" user = "usuario" pass = "senha" dbname = "nome_do_banco" |
Esse é um simples exemplo de um arquivo .ini
, com configurações para acesso a um banco de dados.
Carregando Dados do Arquivo
Vaamos agora criar o script que carrega uma configuração diretamente do arquivo.
$configFile = 'config.ini'; $start = microtime( true ); $config = parse_ini_file( $configFile, true ); $host = $config[ 'db' ][ 'host' ]; $end = microtime( true ); var_dump( $host ); var_dump( number_format( $end - $start, 20 ) ); |
No meu computador, o tempo de execução exibido foi 0.00008392333984375000.
Carregando Dados do Cache
Nesse script, vamos carregar o conteúdo do arquivo .ini
e salvá-lo no cache. Apenas depois disso vamos contabilizar o tempo. Afinal, estamos interessados apenas no tempo de acesso ao cache.
$configFile = 'config.ini'; $configArr = parse_ini_file( $configFile, true ); apc_store( 'config', $configArr, 5 ); $start = microtime( true ); $config = apc_fetch( 'config' ); $host = $config[ 'db' ][ 'host' ]; $end = microtime( true ); var_dump( $host ); var_dump( number_format( $end - $start, 20 ) ); |
O resultado retornado foi 0.00001096725463867188.
Comparando os Resultados
O tempo de execução do primeiro script foi de 0.00008392333984375000 segundos. O segundo levou 0.00001096725463867188. Se dividirmos ambos os números, veremos que o script que acessa o cache rodou, aproximadamente, 7.652174 vezes mais rápido!
Conclusão
O uso de cache acelera bastante a execução dos nossos sistemas.
O APC é apenas uma das opções de cache para PHP. Existem diversas outras. Não importa muito qual você usará, mas é importante que seja usado cache para armazenar informações que são acessadas com frequência, como dados de um arquivo de configuração, como usei no exemplo.
Latest posts by Roberto Beraldo (see all)
- Não Tenha Preguiça de Ler! - 25/04/2016
- Como Atualizar Scripts PHP de MySQL Para MySQLi - 29/10/2015
- Como usar PDO com banco de dados MySQL - 10/09/2015