Benchmark - Análise de performance
Criei uma classe simples que analisa diferentes alternativas de códigos e informa, a fins de estudo, qual é mais rápida que a outra. Espero que ajude alguém... lá vai:
- Code atualizado: estava com problema no cálculo percentual. Creio que agora esteja correto.
<?php
/**
* Timer Class - Simple benchmark solution for PHP
* @author Matheus Tavares <contato at matheustavares . com . br>
* @license Creative Commons BY-NC
*/
final class Timer {
private $_start, $_difference = 0;
/**
* Starts a benchmark
* @return string
*/
public function benchmark() {
if ( ( $num_args = func_num_args() ) < 1 ) :
trigger_error(
'You must set at least one function as argument'
);
return false;
endif;
$timer_index = 0;
$output = '';
foreach( func_get_args() as $function ):
$this->start();
$function();
$this->stop();
$timer[ ++$timer_index ] = $this->get();
$output .= sprintf(
'Timer <b>#%d:</b> %.7f<br />',
$timer_index , $this->get()
);
$this->reset();
endforeach;
if ( $num_args > 1 ) :
asort( $timer , SORT_NUMERIC );
$keys = array_keys( $timer );
$min = array_shift( $timer );
$max = end( $timer );
$percent = self::percentDiff( $min , $max );
$output .= sprintf(
'The timer <b>#%d</b> (fastest) is <b>%.2f%%</b>
faster than timer <b>#%d</b> (slowest)',
array_shift( $keys ) , $percent , end( $keys )
);
endif;
return $output;
}
/**
* Starts the counter
* @return void
*/
public function start() {
$this->_start = self::getMicrotime();
}
/**
* Stops the counter
* @return void
*/
public function stop() {
$difference = self::getMicrotime() - $this->_start;
$this->_difference += $difference;
}
/**
* Gets the counter
* @return float
*/
public function get() {
return $this->_difference;
}
/**
* Resets the counter
* @return void
*/
public function reset() {
$this->_difference = 0;
}
/**
* Improved variant of microtime() function
* @param int $e
* @return float
*/
public static function getMicrotime( $e = 7 ) {
list( $usec , $sec ) = explode( ' ', microtime() );
return bcadd( $usec , $sec , $e );
}
/**
* Gets the difference between 2 numbers, in percent
* @param float $min
* @param float $max
* @return float The percent
*/
public static function percentDiff( $min , $max ) {
return ( ( $max - $min ) / $min ) * 100;
}
}
Exemplo de uso:
<?php
$timer = new Timer();
echo $timer->benchmark(
function() {
$var = 0;
for( $i = 0 ; $i < 50000 ; $i++ )
$var = $var+1;
},
function() {
$var = 0;
for( $i = 0 ; $i < 50000 ; $i++ )
$var += 1;
}
);
Resultado:
Timer #1: 0.0030301Timer #2: 0.0026171
The timer #2 (fastest) is 15.78% faster than timer #1 (slowest)
Conclusões com o resultado:
Na soma de um valor à uma variável, utilizar $var += 1; é aproximadamente 15% mais rápido que $var = $var + 1;
Obs: Pode-se adicionar no método benchmark() quantas funções forem necessárias. Caso queira comparar 5 comportamento diferentes, basta adicionar as respectivas funções.
Obs2: Pode-se também utilizar os métodos separadamente: start() / stop() / get(), caso não queira utilizar o benchmark().
Alguma sugestão? Fiz em pouco tempo e testei poucas vezes ainda... dúvidas, dicas e críticas são bem-vindas.
[]'s!
Discussão (3)
Carregando comentários...