1 2 3 4 5 6
<?php function getsize ($size) { $si = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); return round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $si[$i]; } ?>
Refactorings
No refactoring yet !
Paul Kemper
October 6, 2007, October 06, 2007 12:43, permalink
Surely using shift operations and simple additions must be faster that using the expensive math functions. And using a string is possibly faster in setup that an array. The code is longer, but executes faster is my guess.
1 2 3 4 5 6 7 8
<?php function getsize( $size ) { $si = ' KMGTPEZY'; for ( $i=0; $size>=1024; $size>>10,$i++ ); return $si{$i}.'B'; } ?>
Rudie
October 6, 2007, October 06, 2007 13:43, permalink
Paul, your code doesn't do exactly what the original code does. It doesn't output a number for the unit created.
I've taken a little of both functions and created this. It proves to be the fastest. 100.000 executions in (avg) 0.93 sec, versus the initial version's 1.03 sec.
1 2 3 4 5 6 7 8
<?php function bytes_to_readable1( $a, $b = 2 ) { $c = ' KMGTPEZY'; return round($a / pow(1024, ($i = floor(log($a, 1024)))), $b) . ' ' . trim($c[$i]).'B'; } ?>
Mike Cochrane
October 8, 2007, October 08, 2007 01:52, permalink
My code does everything with bit shifts. Also doesn't output a divide by zero error when size = 0. In my trials it completes in 49% of the time of the original. My code is not 100% equivalent - when size = 0 my code returns '0 B', the original returns '0 '.
1 2 3 4 5 6 7 8 9 10
function getsize($size) {
$si = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
$remainder = $i = 0;
while ($size >= 1024 && $i < 8) {
$remainder = $size & 0x3ff;
$size = $size >> 10;
$i++;
}
return round($size + ($remainder/1024), 2) . ' ' . $si[$i];
}
Mike Cochrane
October 8, 2007, October 08, 2007 02:17, permalink
Okay, there was a bug in my rounding code. Here's the corrected version. Completes in 51% of the time of the original.
1 2 3 4 5 6 7 8 9 10 11
<?php function getsize($size) { $si = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); $remainder = $i = 0; while ($size >= 1024 && $i < 8) { $remainder = (($size & 0x3ff) + $remainder) / 1024; $size = $size >> 10; $i++; } return round($size + $remainder, 2) . ' ' . $si[$i]; }
Mike Cochrane
October 8, 2007, October 08, 2007 05:07, permalink
> Make this simpler?
No, I can't make it simpler (from a human point of view) but I can make it faster.
Make this simpler?