Peter Krejci
Peter Krejci

Reputation: 3192

Caching large arrays

I have following function:

function f($idx, $arr) {
    static $a;
    if ($a == NULL) {
        foreach ($arr as $v) {
            $key = $v['key'];
            if (!isset($a[$key])) {
                $a[$key] = array();
            }
            $a[$key][] = $v;
        }
    }

    return $a[$idx];
}

And the initial conditions are:

  1. function f() is called many-many times in 1 request
  2. $arr is always very large
  3. $arr may differ in different function calls (low cardinality)
  4. $idx differs almost in every function call (high cardinality)

And now I need to know, if $arr is already cached and if not, then create this "cached version", but keep also all previous arrays.

According to 2. I'm not able to use md5(serialize($arr)) to use it as identifier, so I need another way to determine that. Do you have any idea how to achieve such hight-performance caching functionality (let's say I'm not able to do any changes outside this function)?

Upvotes: 0

Views: 124

Answers (1)

Jason
Jason

Reputation: 13766

If it's not imperative that $arr not be modified, then I'd just add your optimized key access directly to it:

// note the argument has been changed to &$arr - we're passing by reference
function f($idx, &$arr) {
    if (empty($arr['___cached'])) {
        $arr['___cached'] = array();
        foreach ($arr as $k => $v) {
            if ($k === '___cached') continue;
            if (!isset($arr['___cached'][$v['key']])) {
                $arr['___cached'][$v['key']] = array();
            }
            $arr['___cached'][$v['key']][] = $v;
        }
    }

    return $arr['___cached'][$idx];
}

Upvotes: 1

Related Questions