查找表:数组与开关/案例性能

时间:2015-07-16 07:44:47

标签: php arrays performance lookup-tables

在PHP应用程序中,我有一个非常大的常量(文字)查找表,其形式为三维数组,前两个维度中包含字符串键,第三个维度为非关联,并且在第二级(一些整个第三维数组重复出现)。

来自像C ++这样的编译语言,我更喜欢这样的查找表,因为它们几乎不会产生运行时成本(代码中只有缓存未命中是一个问题)。所以我在PHP中定义它是这样的:

$table = array(
    '182-0' => array(
        '221-0' => array()
    ), 
    '184-0' => array(
        '197-0' => array('1.9','1.10','1.11','1.12','1.13','1.14','1.15','1.16','1.17','1.18'), 
        '201-0' => array('1.9','1.10','1.11','1.12','1.13','1.14','1.15','1.16','1.17','1.18'), 
        '221-0' => array('1.19','1.20','1.21','1.22','1.23','1.24','1.25','1.26','1.27','1.28'), 
        '221-1' => ...,
        ...
    ),
    ...
);

此数组在源代码中消耗大约1兆字节,并且是完全静态的。所有这些代码都是无条件执行的,以便创建完整的查找表,然后一个第三维数组每个请求只使用一次

// once per request, for given $a and $b:
foreach ($table[$a][$b] as $item) {
    ...
}

我想对于像这样的代码可能有更好的选择。我猜上面代码的核心问题是数组是在动态的每个请求上构建的,但是因为它只在一次使用时才会使用这个工作几乎没用。

上述代码有什么好的替代方案?我想保存源代码大小和运行时成本。

我应该将其重写为分支吗?还有更好的选择,特别适合常量查找表吗?

我正在考虑像这样的基于分支的解决方案(请注意案例 - 以避免重复第三级数组):

function table($a, $b) {
    switch ($a) {
    case '182-0':
        switch ($b) {
        case '221-0':
            return array();
        default:
            return null;
        }

    case '184-0':
        switch ($b) {
        case '197-0':
        case '201-0':
            return array('1.9','1.10','1.11','1.12','1.13','1.14','1.15','1.16','1.17','1.18');
        case '221-0':
            return array('1.19','1.20','1.21','1.22','1.23','1.24','1.25','1.26','1.27','1.28');
        ...
        default:
            return null;
        }
    }
    ...

    return null;
}

然后将其用于:

// once per request, for given $a and $b:
foreach (table($a, $b) as $item) {
    ...
}

0 个答案:

没有答案