Доступ к большим массивам в PHP

Я делаю некоторые профилирования по различным методам доступа к большим (ish) массивам данных в PHP. Практический пример довольно прост: некоторые из наших инструментов выводят данные в файлы PHP как ассоциативные массивы, и эти файлы считаются статическими данными приложением. Мы делаем игры, поэтому некоторые примеры файлов данных будут включать элементы в каталоге, задачи, которые должен выполнить пользователь, или определения для карт:

<?php $some_data = array( ...lots and lots of stuff in here... ); ?> 

Поскольку эти массивы являются большими (400 КБ), и большая часть нашего кода заинтересована в этих данных, становится необходимо как можно более эффективно получать доступ к этим данным. Я решил использовать 3 разных шаблона для этого. Представляя методы, я поделюсь своими результатами ниже.

То, что я ищу, – это некоторые проверки на основе этих методов и их время, а также любые другие методы, которые можно попробовать.

Метод №1: функция геттера

В методе экспортер фактически создает файл, который выглядит так:

 <?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); 

Результаты

Поэтому я запустил небольшой скрипт, который запускает каждый из этих методов получения данных в 1000 раз и усредняет время выполнения (вычисленное microtime (true) в начале и в конце). Ниже приведены мои результаты (в мс, работающие на MacBookPro 2 ГГц, 8 ГБ оперативной памяти, версия PHP 5.3.4):

СПОСОБ №1:

AVG: 0,0031637034416199 MAX: 0,0043289661407471 МИН: 0.0025908946990967

СПОСОБ № 2:

AVG: 0.01434082698822 MAX: 0.018275022506714 MIN: 0.012722969055176

СПОСОБ № 3:

AVG: 0.00335768699646 MAX: 0.0043489933013916 МИН: 0.0029017925262451

В любом случае представляется очевидным, что из этих данных метод global + include уступает другим, что является «незначительной» разницей.

Мысли? Я что-то совсем не вижу? (вероятно…)

Заранее спасибо!

Related of "Доступ к большим массивам в PHP"

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

 $startMemory = memory_get_usage(); $array = new SplFixedArray(100000); for ($i = 0; $i < 100000; ++$i) { $array[$i] = $i; } echo memory_get_usage() - $startMemory, ' bytes'; 

Подробнее о больших массивах php читайте здесь: http://nikic.github.com/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html

Также вы подумали о хранении данных в кеше / памяти? Например, вы можете использовать mysqlite с движком inmemory при первом выполнении, а затем получить доступ к данным:

 $pdo = new PDO('sqlite::memory:'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // .. Use PDO as normal 

Для одного из моих проектов, в которых база данных не была вариантом, я столкнулся с такой же проблемой загрузки больших (по большому счету, я имею в виду серии из 3 Мбайт файлов) php-файлов, содержащих массивы в памяти, и я искал варианты для максимизации производительности. Я нашел очень простой, который кешировал эти файлы на диске как json при первом использовании. Я разделил время загрузки на 3, а пиковое потребление памяти на 30%. Загрузка локального json-файла с помощью json_decode () намного быстрее, чем включение большого файла php, содержащего массив. это также имеет преимущество в том, что формат, который большинство языков может манипулировать напрямую. Надеюсь, это поможет.