Я только что провел этот очень интересный эксперимент, и результаты вышли довольно неожиданно.Возвращаемый массив быстрее, чем возврат элемента массива
Целью теста было определить наилучший способ, с точки зрения производительности, получить элемент массива. Причина в том, что у меня есть класс конфигурации, который содержит настройки в ассоциативном муфтийном массиве, и я не был уверен, что получаю эти значения наилучшим образом.
данных (это на самом деле не нужны для вопроса, но я решил включить его, так что вы видите, что это вполне разумное количество данных для выполнения тестов с)
$data = array('system' => [
'GUI' =>
array(
'enabled' => true,
'password' => '',
),
'Constants' => array(
'URL_QUERYSTRING' => true,
'ERRORS_TO_EXCEPTIONS' => true,
'DEBUG_MODE' => true,
),
'Benchmark' =>
array(
'enabled' => false,
),
'Translations' =>
array(
'db_connection' => 'Default',
'table_name' =>
array(
'languages' => 'languages',
'translations' => 'translations',
),
),
'Spam' =>
array(
'honeypot_names' =>
array(
0 => 'name1',
1 => 'name2',
2 => 'name3',
3 => 'name4',
4 => 'name5',
5 => 'name6',
),
),
'Response' =>
array(
'supported' =>
array(
0 => 'text/html',
1 => 'application/json',
),
),]
);
Методы
function plain($file, $setting, $key, $sub){
global $data;
return $data[$file][$setting][$key][$sub];
}
function loop(...$args){
global $data;
$value = $data[array_shift($args)];
foreach($args as $arg){
$value = $value[$arg];
}
return $value;
}
function arr(){
global $data;
return $data;
}
Параметры (при вызове функции)
loop('system', 'Translations', 'table_name', 'languages');
plain('system', 'Translations', 'table_name', 'languages');
arr()['system']['Translations']['table_name']['languages'];
Оставив в стороне любые другие возможные недостатки и сосредоточив внимание только на производительности, я провел 50 тестов с использованием 10000 циклов. Каждая функция была вызвана всего 500000 раз. Результаты приведены в среднем секундах на 10000 петель:
loop: 100% - 0.0381 сек. Возврат: языки
равнина: 38% - 0.0146 сек. Возвращения: Языки
обр: 23% - 0.0088 сек. Возвращает: языки
Я ожидал loop
быть довольно медленным, потому что есть логика внутри, но, глядя на результаты двух других я был очень удивлен. Я ожидал, что plain
будет самым быстрым, потому что я возвращаю элемент из массива, и по другой причине arr
будет самым медленным, потому что он возвращает весь массив.
Учитывая исход эксперимента, у меня есть 2 вопроса.
- Почему
arr
почти в 2 раза быстрее, чемplain
? - Есть ли какие-либо другие методы, которые я пропустил, которые могут превзойти
arr
?
Ваши ожидания ошибочны, почему ** не будет ** быстрее возвращать массив, а затем на самом деле перебирать весь массив, чтобы найти определенное значение по ключу? Даже когда вы используете скобки и поставляете ключ, итерация должна произойти, чтобы найти этот ключ. – adeneo
@adeneo в случае 'plain', он не выполняет итерацию массива, кроме того, когда я вызываю' arr', а затем предоставляю ключи элементу, к которому я хочу перейти, я фактически делаю то же, что и 'plain' внутренне, так как результат, это то, что мне интересно. –
Все, что вам нужно сделать, чтобы вернуть массив, - это вернуть _reference_. Если вы возвращаете один элемент, вы также можете возвращать ссылку, _but_ он должен делать косвенный поиск в массиве _before_ return –