Глядя на Pimple исходный код Я обнаружил, что он хранит объекты и их идентификаторы в двух разных массивах:
class Container implements \ArrayAccess
{
private $values = array();
...
private $keys = array();
}
А потом:
public function offsetSet($id, $value)
{
...
$this->values[$id] = $value;
$this->keys[$id] = true;
}
И наконец:
public function offsetGet($id)
{
if (!isset($this->keys[$id])) {
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
}
}
Я также видел нечто подобное в исходном коде Phalcon. Вот.
Мой вопрос: зачем хранить ключ идентификатора объекта отдельно, а не просто if (!isset($this->values[$id]))
? Это быстрее искать в массиве? Я сделал несколько тестов, и кажется, что скорость поиска практически одинакова.
Хорошо, похоже, что когда значение записи массива может быть null
Вы должны проверить наличие ключа с array_key_exists()
функция. Однако это в несколько раз медленнее, чем isset()
Таким образом, наличие ключей в отдельном массиве позволяет использовать isset()
,
Но лучший способ был бы if (isset(...) || array_key_exists(...))
, который имеет почти такую же скорость, как простой isset()
, но устраняет необходимость в отдельном массиве для отслеживания ключей (спасибо, @ doydoy44).
Других решений пока нет …