Nickolay.info. PHP. Статьи. Класс для измерения временных промежутков и проверка существования функции

Измерение временного промежутка, в течение которого исполняется тот или иной код - типовая задача, решаемая, в том числе, и на PHP. Один из вариантов современного подхода к такой задаче показывает небольшой класс CheckTimeInterval.php, листинг которого приведён ниже:

<?php
class CheckTimeInterval {
 public $start,$end;
 public function function_enabled($func) {
  //Функция проверки существования и доступности другой функции PHP
  //Параметры: $func - строка имени функции
  //На выходе: true - функция есть и доступна для вызова,
  //           false - функция недоступна
  $func=strtolower(trim($func));
  if ($func=='') return false;
  //Получить список функций, отключенных в php.ini
  $disabled=explode(",",@ini_get("disable_functions"));
  if (empty($disabled)) { $disabled=array(); }
  else { 
   //Убрать пробелы и привести названия к нижнему регистру
   $disabled=array_map('trim',array_map('strtolower',$disabled));
  }
  //Проверить доступность функции разными способами
  return (function_exists($func) && is_callable($func) && !in_array($func,$disabled));
 }

 public function __construct () {
  if ($this->function_enabled('microtime')===false or 
      version_compare(PHP_VERSION, '5.0.0', '<')) $this->start = false;
  else $this->begin();
 }

 public function begin() {
  if ($this->start === false) return false;
  else {
   $this->start = microtime(true);
   return $this->start;
  }
 }

 public function end() {
  if ($this->start === false) return false;
  else {
   $this->end = microtime(true);
   return $this->end - $this->start;
  }
 }
}
?>

Конструктор класса проверяет, доступна ли функция microtime и установлена ли версия PHP не ниже 5. Дело в том, что стандартная microtime может быть доступна не во всех операционных системах. Для проверки существования функции вызывается метод с именем function_enabled - полагаю, его можно использовать и в других скриптах. Версия не ниже 5.0.0 нужна потому, что только в ней появился вызов функции microtime с параметром true, позволяющим вернуть из функции действительное число, которое можно затем интерпретировать как количество секунд. Обеспечить совместимость с младшими версиями PHP, впрочем, тоже несложно - вместо строк вида

$this->start = microtime(true);

достаточно поставить

$this->start = array_sum(explode(' ', microtime()));

- просто это будет работать медленнее и может исказить снятие меток времени.

Чтобы снять начальную метку времени повторно (для уже существующего экземпляра класса CheckTimeInterval), можно вызвать метод begin.

Чтобы получить прошедшее от начала измерения время в секундах, нужно вызвать метод end.

Вот файл index.php - тест класса, отвечающий на 2 типовых для PHP вопроса - отличается ли по быстродействию код с одинарными и двойными кавычками и дают ли выигрыш во времени стандартные функции обработки массивов (в данном случае - функция поиска по массиву с числовыми ключами 0,1,2...)

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Тест класса CheckTimeInterval</title>
</head><body>
<?php
 require_once 'CheckTimeInterval.php';
 $steps = 100000;
 echo 'Число шагов цикла: '.$steps;
 $s='';
 $timer1 = new CheckTimeInterval ();
 if ($timer1->start===false) {
  echo '<br>Функция microtime(true) недоступна для Вашего сервера';
 }
 else {
  for ($i=0; $i<$steps; $i++) $s.=$i;
  $time1=$timer1->end();
  echo '<br>Формирование строки без двойных кавычек: '.$time1.' с.';
  $s2='';
  $timer2 = new CheckTimeInterval ();
  for ($i=0; $i<$steps; $i++) $s2.="$i";
  $time2=$timer2->end();
  echo '<br>Формирование строки с двойными кавычками: '.$time2.' с.';

  for ($i=0; $i<$steps; $i++) $array[$i]=$i;
  $needle=$steps-1;
  $timer1->begin();
  $key=array_search ($needle,$array);
  $time1=$timer1->end();
  echo '<br>Поиск в массиве стандартной функцией: '.$time1.' с.';
  $timer2->begin();
  for ($i=0; $i<$steps; $i++) {
   if ($array[$i]==$needle) { $key=$i; break; }
  }
  $time2=$timer2->end();
  echo '<br>Поиск в массиве "вручную": '.$time2.' с.';
 }
 echo '<br><a href="index.php">Попробовать ещё раз</a> (результаты будут отличаться на разных тестах)';
?>
</body></html>

При первом запуске получилось следующее:

Число шагов цикла: 100000
Формирование строки без двойных кавычек: 0.0742630958557 с.
Формирование строки с двойными кавычками: 0.0890390872955 с.
Поиск в массиве стандартной функцией: 0.00933218002319 с.
Поиск в массиве "вручную": 0.0216920375824 с.

Результаты будут отличаться при перезагрузках страницы - что там PHP кэширует и чем ещё заняты процессоры при выполнении скрипта - одному Богу известно.

При каком максимальном значении переменной $steps скрипт будет работать - зависит от настройки memory_limit в Вашем файле конфигурации php.ini

То же самое намного проще

В целом, думаю, не нужно догматизма насчёт того, что "одинарные кавычки лучше" или наоборот.

Всё зависит от ситуации. Например, показанная ниже мини-версия этого класса, тестирующая работу с массивом из миллиона элементов, даёт стабильное преимущество... как раз двойным кавычкам. Дело в том, что попросту чем меньше сцеплений строк, тем лучше.

<?php
 class Timer {
  public $start, $end;
  public function __construct () { 
   $this->start = microtime(true); return $this->start; 
  }	 
  public function end () { 
   $this->end = microtime(true); 
   return $this->end-$this->start; 
  }
 }
 
 $steps = 1000000; 
 for ($i=1; $i<=$steps; $i++) $arr[] = $i;
 //тест кавычек с массивом
 $s = ''; $t1 = new Timer(); 
 for ($i=0; $i<$steps;$i++) $s .= 'Arr='.$arr[$i].','.$i;
 echo 'С апострофами: '.$t1->end().'<br>';
 $s = ''; $t2 = new Timer(); 
 for ($i=0; $i<$steps;$i++) $s .= "Arr={$arr[$i]},$i";
 echo 'С двойными кавычками: '.$t2->end().'<br>';
?>
С апострофами: 0.28701686859131
С двойными кавычками: 0.2216119766235

Рейтинг@Mail.ru

вверх гостевая; E-mail