我正在为APC寻找一个好的缓存密钥,它代表一些关于对象的编译信息,使用“对象”作为密钥.我有一个编译方法,它做这样的事情:
function compile(Obj $obj)
{
if ($this->cache)
{
$cachekey = serialize($obj);
if ($data = $this->cache->get($obj))
{
return $data
}
}
// compute result here
if ($this->cache)
{
$this->cache->set($cachekey, $result);
}
return $result;
}
如果不明显,$this-> cache是具有get和set方法的接口的实现.
是否有更快的替代方法来创建对象的某些属性所特有的键?我可以提取相关的位,但是它们仍然是数组,这与我首先使用对象的序列化具有相同的问题.
Serialize从“正确”位置开始工作,但看起来很浪费(输出密钥的大小和计算复杂性).
编辑:我还想补充说,如果不是很明显,我将不需要反序列化这个对象.我当前缓存键的逐字代码实际上是:
$cachekey =’compile.’ . SHA1(连载($OBJ));.
编辑2:我正在使用的对象具有以下定义:
class Route
{
protected $pattern;
protected $defaults = array();
protected $requirements = array();
}
模式和要求是将更改此方法的输出的对象的值,因此这些值的哈希值必须存在于缓存键中.
此外,有人建议使用uniqid(),这会破坏通用缓存查找键的目的,因为您无法从相同的信息中可靠地重新生成相同的ID.
编辑3:我想我没有提供足够的背景.这是到目前为止代码的链接:
https://github.com/efritz/minuet/blob/master/src/Minuet/Routing/Router.php#L160
我想我真的只是想避免昂贵的序列化调用(我猜sha1,这也有点贵).我能做的最好的事情是尝试减少我序列化的大小…
最佳答案 一种方法可能是简单地根据用于计算结果的值生成密钥.
这是一个粗略的例子.
function compile(Obj $obj)
{
if ($this->cache)
{
$cachekey = 'Obj-result-' . sha1($obj->pattern . '-' . serialize($obj->requirements));
// You could even try print_r($obj->requirements, true)
// or even json_encode($obj->requirements)
// or implode('-', $obj->requirements)
// Can't say for sure which is slowest, or fastest.
if ($data = $this->cache->get($cachekey))
{
return $data
}
}
// compute result here
$result = $obj->x + $obj->y; // irrelevant, and from original answer.
if ($this->cache)
{
$this->cache->set($cachekey, $result);
}
return $result;
}
既然你使用了一个数组,你仍然需要把它变成一个有意义的东西.但是这样你现在只是序列化一部分对象,而不是整个事物.看看它如何. 🙂