02 марта 2006

Быстрый счётчик посещений

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

А почему бы не использовать атрибуты файла? Ну например, размер? За каждое обращение счётчик тупо дописывает 1 символ в файл, а когда нужно получить общую сумму, просто возвращает размер файла. Просто? Да. Быстро? Очень. Я погонял вот эти две функции получения общего количества значений, результат таков: 0.6 секунды занял мой новый вариант против 10.7 секунд традиционного. Обе функции пускались 50 тыщ раз.

function func()
{
  global $file;
  return filesize($file);
}

function func2()
{
  global $file2;
  $fp = fopen($file2, "r");
  $count = (int)fread($fp, 10);
  fclose($fp);
  return $count;
}

Это всё хорошо, скажите вы, а что с записью? Ну тут не такое уж ускорение, и всё же... Вот две функции увеличения на 1 количества обращений:

function func()
{
  global $file;
  $fp = fopen($file, 'a');
  fwrite($fp, "1");
  fclose($fp);
  return 1;
}

function func2()
{
  global $file2;
  $fp = fopen($file2, "r");
  $count = (int)fread($fp, 10);
  fclose($fp);
  $fp = fopen($file2, "w");
  fwrite($fp, $count+1);
  fclose($fp);
  return 1;
}


Эти функцайки я тоже пустил 50 тыщ раз. 14 vs 30 секунд - первый вариант более чем в 2 раза быстрее. Что приятно: оба счётчика вернули в конце одинаковый результат. Что менее приятно: мой способ жрёт больше места - "мой" файл после теста стал весить 50000 байт, а "традиционный" - 5.

Зато! Зато мой способ легко может использоваться для сбора ежедневной статистики помимо общей: перед записью нужно проверить, менялся ли файл сегодня: если да, то просто дописываем единичку в конец, а если нет, то дописываем перенос строки; таким образом, для каждого дня будем иметь строку с числом посещений (в первый день зашло 10 человек, значит, 10 единичек; во второй день - 20 человек, значит, имеем 1 перенос строки + 19 единичек), можно графики строить! И считывание счётчика не будет врать. В традиционном способе тоже можно выдялить по строке на день, но и попариться со считыванием-инкрементом-записью придётся немного больше.

При тесте производительности ни одной функции не пострадало. Для тестов использовался измерительный движок Дмитрия Бородина.

0 комментов:

Отправить комментарий