Я занимался профилированием различных методов доступа к массивам больших (ish) данных в PHP. Практический пример довольно прост: некоторые из наших инструментов выводят данные в файлы PHP как ассоциативные массивы, и эти файлы считаются статическими данными приложением. Мы делаем игры, поэтому некоторые примеры файлов данных будут включать элементы в каталоге, задачи, которые должен выполнить пользователь, или определения для карт:
<?php
$some_data = array(
...lots and lots of stuff in here...
);
?>
Поскольку эти массивы являются большими (400 КБ), и большая часть нашего кода заинтересована в этих данных, становится необходимо как можно более эффективно получать доступ к этим данным. Я решил использовать 3 разных шаблона для этого. Представляя методы, я поделюсь своими результатами ниже.
То, что я ищу, - это некоторые проверки на основе этих методов и их время, а также любые другие методы, которые можно попробовать.
Метод # 1: функция getter
В этом методе экспортер фактически создает файл, который выглядит так:
<?php
function getSomeData()
{
$some_data = array(
...lots and lots of stuff here...
);
return $some_data;
}
?>
Клиентский код может затем получить данные, просто вызвав getSomeData(), когда они этого захотят.
Метод # 2: глобальный + включить
В этом методе файл данных выглядит идентично исходному коду блока выше, однако клиентский код должен перескакивать через несколько обручей, чтобы получить данные в локальной области. Это предполагает, что массив находится в файле с именем 'some_data.php';
global $some_data; //must be the same name as the variable in the data file...
include 'some_data.php';
Это приведет к массиву $some_data в область видимости, хотя это немного громоздко для кода клиента (мое мнение).
Метод № 3: получение по ссылке
Этот метод почти идентичен методу # 1, однако функция getter не возвращает значение, а скорее задает ссылку на данные.
<?php
function getSomeDataByRef($some_data)
{
$some_data = array(
...lots and lots of stuff here...
);
return $some_data;
}
?>
Затем код клиента извлекает данные, объявляя локальную переменную (называемую чем угодно) и передавая ее по ссылке на getter:
$some_data_anyname = array();
getSomeDataByRef(&$some_data_anyname);
Результаты
Итак, я запустил немного script, который запускает каждый из этих методов получения данных 1000 раз и усредняет время выполнения (вычисленное microtime (true) в начале и в конце). Ниже приведены мои результаты (в мс, работающие на MacBookPro 2 ГГц, 8 ГБ оперативной памяти, версия PHP 5.3.4):
МЕТОД №1:
AVG: 0,0031637034416199 MAX: 0,0043289661407471 MIN: 0.0025908946990967
МЕТОД № 2:
AVG: 0.01434082698822 MAX: 0,018275022506714 MIN: 0.012722969055176
МЕТОД № 3:
AVG: 0,00335768699646 MAX: 0,0043489933013916 MIN: 0.0029017925262451
В любом случае, из этих данных ясно, что метод global + include уступает другим, что является "незначительной" разницей.
Мысли? Я что-то совсем не вижу? (Наверное...)
Спасибо заранее!