疙瘩源码:为什么要把object id和object本身存放在不同的数组中?
Pimple source code: Why to store object id and object itself in different arrays?
查看 Pimple source code 我发现它在两个不同的数组中存储对象及其 ID:
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 源代码中也看到了类似的东西 here。
我的问题是为什么要单独存储对象 ID 键,为什么不 if (!isset($this->values[$id]))
?在数组中搜索是否更快?我做了一些测试,搜索速度好像差不多。
好的,似乎当数组条目值可能是 null
时,您必须使用 array_key_exists()
函数检查键是否存在。但是,这比 isset()
慢几倍,因此在单独的数组中有键可以使用 isset()
。
但更好的方法是 if (isset(...) || array_key_exists(...))
,它的速度几乎与简单的 isset()
相同,但不需要单独的数组来跟踪键(感谢 @doydoy44)。
查看 Pimple source code 我发现它在两个不同的数组中存储对象及其 ID:
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 源代码中也看到了类似的东西 here。
我的问题是为什么要单独存储对象 ID 键,为什么不 if (!isset($this->values[$id]))
?在数组中搜索是否更快?我做了一些测试,搜索速度好像差不多。
好的,似乎当数组条目值可能是 null
时,您必须使用 array_key_exists()
函数检查键是否存在。但是,这比 isset()
慢几倍,因此在单独的数组中有键可以使用 isset()
。
但更好的方法是 if (isset(...) || array_key_exists(...))
,它的速度几乎与简单的 isset()
相同,但不需要单独的数组来跟踪键(感谢 @doydoy44)。