Reputation: 5203
I'm looking for a good cache key for APC that represents some complied information about an object, using the "object" as the key. I have a compilation method that does something like this:
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;
}
If it's not obvious, $this->cache
is an implementation of an interface with the methods get
and set
.
Is there a quicker alternative to creating a key that's unique to some of the properties of this object? I can extract the relevant bits out, but then they are still arrays, which would have the same problem with serialization that I had with the objects in the first place.
Serialize works, from a "correctness" position, but it seems wasteful (both in size of outputted key, and in computational complexity).
EDIT: I would also like to add, if it's not obvious, that I will not be needing to unserialize this object. My verbatim code for the current cache key is actually:
$cachekey = 'compile.' . sha1(serialize($obj));
.
EDIT 2: The object I'm working with has the following definition:
class Route
{
protected $pattern;
protected $defaults = array();
protected $requirements = array();
}
Pattern
and requirements
are the values of the object that will change the output of this method, therefore a hash of these values must be present in the cache key.
Also, someone suggested uniqid(), which would defeat the purpose of a general cache lookup key, as you could not reliably regenerate the same ID from the same information.
EDIT 3: I guess I'm not giving enough context. Here's a link to the code so far:
https://github.com/efritz/minuet/blob/master/src/Minuet/Routing/Router.php#L160
I guess I'm really only trying to avoid expensive calls to serialize (and I guess sha1, which is also a bit expensive). It's possible that the best I can do is try to reduce the size of what I'm serializing...
Upvotes: 4
Views: 3312
Reputation: 1701
I would suggest the spl_object_hash
function that seems to fit perfectly for your needs.
Upvotes: 1
Reputation: 299
One way to do it might be to generate a key based simply from the values you use to compute the result..
Here is a rough example.
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;
}
Since you use an array of data, you'd still need to turn it into something that makes sense as a key.. However this way you're now only serializing a part of the object, rather then the whole thing. See how it goes. :)
Upvotes: 1
Reputation: 7748
Actually it is very hard to suggest any viable solution without knowing how the whole system works.
But, Why don't you just simply add a cache_key
property with a uniqid()
value in your object?
Upvotes: 0