Жесткая ссылка
Жесткая ссылка — переменная, представляющая собой синоним другой переменной, на которую она ссылается. Чтобы создать жесткую ссылку, перед переменной необходимо написать "&".
Пример объявления жесткой ссылки:
$a = 1 ; // Некоторая переменная $b = &$a ; // $b ссылается на $a echo $b ; // 1
По сабжу
Многие из нас сталкивались с такой задачей: необходимо получить искомый нами объект, из массива однотипных объектов. Безусловно, эта тривиальная задача, и она легко решается при помощи обычного цикла, но, предположим, что наш массив состоит из довольно большого количества элементов. В этом случае цикл губильно сказывается на производительности в общем. Кроме того, если эта задача будет выполняться неоднократно, это еще больше усугубит ситуацию.
Для решения этой задачи прекрасно подойдет массив-связка, содержащий жесткие ссылки, каждая из которых находится под своим уникальным ключом, полученным путем хеширования.
Наглядно, что представляет из себя это решение:

Скрипт для тестирования
Пропускаем, и смотрим код в целом, если не хочется читать процесс сборки кода
1. Собираем тестовый массив объектов.
class Main { public $List = Array(); // Исходный массив из объектов public $Links = Array(); // Массив жестких ссылок на объекты public $Count = NULL ; // Размер исходного массива public function Fill() // Заполняем массивы { for( $i=0; $i < $this->Count; $i++ ) { $Obj = &$this->List[]; // Заполняем исходный массив $Obj = new Obj($i); $Key = md5($i); $this->Links[$Key] = &$Obj; // Создаем ссылку на объект } } } class Obj // Сам объект { public $Id = NULL; public function __construct( $Id ) { $this->Id = $Id; } } $Main = new Main(); $Main->Count = 1000; // Количество элементов, которое будет в исходном массиве $Main->Fill(); /* Вид собранного массива, print_r( $Main->List ): Array ( [0] => Obj Object ( [Id] => 0 ) [1] => Obj Object ( [Id] => 1 ) [2] => Obj Object ( [Id] => 2 ) ... ) */
1. Определяем функции поиска элемента по ID (циклом, и через ссылки).
class Main { ... public function Search_Cycle( $Id ) { $Limit = count( $this->List ); for( $i=0; $i < $Limit; $i++ ) if( $this->List[$i]->Id == $Id ) return $this->List[$i]; return NULL; } public function Search_Link( $Id ) { $Key = md5($i); if( isset( $this->Links[$Key] ) == TRUE ) return $this->Links[$Key]; return NULL; } ... }
Стоит заметить, что алгоритм поиска элемента построен на генерируемых ключах, и следовательно, не зависит от размера массива, в котором ведется поиск элемента. Из этого следует вывод, что в процессе тестирования, этот алгоритм покажет идентичные результаты на всех этапах.
3. Допишем код для проведения теста
... $Count = 100 ; // Количество вызывов функций поиска элемента в массиве // Каждый тест будет проводиться 10 раз for( $t=0; $t < $Main->Count; $t++ ) { echo 'Test with ID: ' . $t . ' - started.'; // Тест на производительность, используя функцию поиска с циклом $Start = microtime( TRUE ); for( $i=0; $i < $Count; $i++ ) $Main->Search_Cycle( $t ); $Time = round( microtime( TRUE ) - $Start , 4 ); echo '<br />Search_Cycle() time: ' . $Time; // Тест на производительность, используя функцию поиска через ссылки $Start = microtime( TRUE ); for( $i=0; $i < $Count; $i++ ) $Main->Search_Link( $t ); $Time = round( microtime( TRUE ) - $Start , 4 ); echo '<br /> Search_Link() time: ' . $Time; echo '<br /><br />'; }
Этот код выполняет поиск каждого элемента исходного массива ( $Count раз ), используя эти две функции, считает время поиска для каждой, и выводит результат.
Код в целом
В итоге должен получиться вот такой код:
class Main { public $List = Array(); // Исходный массив из объектов public $Links = Array(); // Массив жестких ссылок на объекты public $Count = NULL ; // Размер исходного массива public function Fill() // Заполняем массивы { for( $i=0; $i < $this->Count; $i++ ) { $Obj = &$this->List[]; // Заполняем исходный массив $Obj = new Obj($i); $Key = md5($i); $this->Links[$Key] = &$Obj; // Создаем ссылку на объект } } public function Search_Cycle( $Id ) { $Limit = count( $this->List ); for( $i=0; $i < $Limit; $i++ ) if( $this->List[$i]->Id == $Id ) return $this->List[$i]; return NULL; } public function Search_Link( $Id ) { $Key = md5($Id); if( isset( $this->Links[$Key] ) == TRUE ) return $this->Links[$Key]; return NULL; } } class Obj // Сам объект { public $Id = NULL; public function __construct( $Id ) { $this->Id = $Id; } } $Main = new Main(); $Main->Count = 1000; // Количество элементов, которое будет в исходном массиве $Main->Fill(); /* Вид собранного массива, print_r( $Main->List ): Array ( [0] => Obj Object ( [Id] => 0 ) [1] => Obj Object ( [Id] => 1 ) [2] => Obj Object ( [Id] => 2 ) ... ) */ $Count = 100 ; // Количество вызывов функций поиска элемента в массиве // Каждый тест будет проводиться 10 раз for( $t=0; $t < $Main->Count; $t++ ) { echo 'Test with ID: ' . $t . ' - started.'; // Тест на производительность, используя функцию поиска с циклом $Start = microtime( TRUE ); for( $i=0; $i < $Count; $i++ ) $Main->Search_Cycle( $t ); $Time = round( microtime( TRUE ) - $Start , 4 ); echo '<br />Search_Cycle() time: ' . $Time; // Тест на производительность, используя функцию поиска через ссылки $Start = microtime( TRUE ); for( $i=0; $i < $Count; $i++ ) $Main->Search_Link( $t ); $Time = round( microtime( TRUE ) - $Start , 4 ); echo '<br /> Search_Link() time: ' . $Time; echo '<br /><br />'; }
Для тестирования нам достаточно запустить скрипт.
Тестирование
Запустив скрипт, были получены результаты о времени поиска элемента. Так как поиск каждого элемента производился 100 раз подряд (для получения реальных цифр), любое значение которое вы увидите ниже — стоит разделить на сто, для получения максимально реальной картины.
Результаты:
По вертикали на графиках — скорость поиска. По горизонтали — ID искомого объекта.
График к сожалению изображением, поэтому подергать-потыркать нельзя.
Поиск функцией Search_Cycle() — при помощи цикла.

Поиск функцией Search_Link_Cycle() — при помощи жестких ссылок.

Ключевой момент при исследовании этих графиков — поиск при помощи цикла работает быстрее, нежели ссылки, при количестве элементов менее 6 ( 0.002 сек. против 0.004 сек. ).
Итог
Очевидно, что работать с жесткими ссылками намного быстрее, потому что они не зависят от размера массива, и ссылаются напрямую на объект. Тем не менее, они проигрывают поиску опираясь на цикл, при небольшом размере массива (если не учитывать, что эта разница просто ничтожна).
Что использовать — каждый вправе выбирать сам, но используя именно этот метод при поиске в больших массивах, — вы значительно выйграете в производительности, и мгновенно найдете объект, независимо от размера массива.
