这需要这么长时间才能完成吗?

时间:2013-09-13 20:00:41

标签: php

当我将以下代码附加到我的脚本时,我的页面加载从650-700ms到1.5-1.6s:

$authpts = array();
foreach ($obj["pro"] as $key => $val) {
    $c_recs = count($recs);
    for ($i=0; $i<$c_recs; $i++) {
        if ($recs[$i][0] === $key) {
            $wr = $recs[$i][1];
            break;
        }
    }
    $c_val = count($val);
    for ($i=0; $i<$c_val; $i++) {
        if (!array_key_exists($val[$i]["authid"], $authpts))
            $authpts[$val[$i]["authid"]] = 0;
        $ratio = 0;
        if (strlen($c_wr) > 0) {
            $ratio = comparetime($val[$i]["time"], $wr);
            $ratio = $ratio[0];
        }
        $rbonus = ($ratio > 0) ? pow($ratio, (2 / $ratio)) : 0;
        $authpts[$val[$i]["authid"]] = $authpts[$val[$i]["authid"]] + ($c_val - $i) * (1 + $rbonus);
    }
}

现在,如果我的脚本在此处结束,这可能是可以接受的,但是在此之后需要再发生三个类似的循环。目前,如果我启用所有内容,页面加载大约需要15秒,这是完全不可接受的。

$obj["pro"]有大约1500个条目要迭代,$recs大约有3000个。我已尽力优化它,但想知道是否有更有效的方法来执行相同的功能

基本上我需要在$obj["pro"]数组中找到任何出现的字符串(来自外部数组的键$recs)(如果存在的话)(如果有的话应该只有一个匹配;这是为什么我在找到匹配时中断),然后获得匹配索引$recs中包含的相应值。

下一步是在不同的初始空数组($authpts)中创建一个新的数组键,初始值为0(点),然后,如果找到匹配项,则查看每个外部数组数组的键值,并将其中一个(time)与$recs中存储的值进行比较,以计算表示效果的比率奖励。

最后一步是向指数计算的$authpts添加一些积分,如果适用则增加比率奖励。

作为一个注释,当这段代码在javascript中时,完成的时间要少得多。

=========================

编辑:这里是整个calcpoints函数(我不会对其进行描述,因为信息太多,而且大部分都是不言自明的):

function calcpoints($obj, $recs) {
    global $points, $wpnspeeds;
    $authpts = array();
    foreach ($obj["pro"] as $key => $val) {
        $c_recs = count($recs);
        for ($i=0; $i<$c_recs; $i++) {
            if ($recs[$i][0] === $key) {
                $wr = $recs[$i][1];
                break;
            }
        }
        $c_val = count($val);
        for ($i=0; $i<$c_val; $i++) {
            if (!array_key_exists($val[$i]["authid"], $authpts))
                $authpts[$val[$i]["authid"]] = 0;
            $ratio = 0;
            if (strlen($wr) > 0) {
                $ratio = comparetime($val[$i]["time"], $wr);
                $ratio = $ratio[0];
            }
            $rbonus = ($ratio > 0) ? pow($ratio, (2 / $ratio)) : 0;
            $authpts[$val[$i]["authid"]] = $authpts[$val[$i]["authid"]] + ($c_val - $i) * (1 + $rbonus);
        }
    }
    foreach ($obj["nub"] as $val) {
        $c_val = count($val);
        for ($i=0; $i<$c_val; $i++) {
            if (!array_key_exists($val[$i]["authid"], $authpts))
                $authpts[$val[$i]["authid"]] = 0;
            $authpts[$val[$i]["authid"]] = (array_key_exists("gc", $val[$i])) ? $authpts[$val[$i]["authid"]] + ($c_val - $i) * pow(0.98, $val[$i]["gc"]) : $authpts[$val[$i]["authid"]] + ($c_val - $i);
        }
    }
    foreach ($obj["wpn"] as $val) {
        $c_val = count($val);
        for($i=0; $i<$c_val; $i++) {
            if (!array_key_exists($val[$i]["authid"], $authpts))
                $authpts[$val[$i]["authid"]] = 0;
            $wsw = 1;
            if (array_key_exists("weapon", $val[$i]) && array_key_exists($val[$i]["weapon"], $wpnspeeds))
                $wsw = (250 - $wpnspeeds[$val[$i]["weapon"]]) / (250 - $wpnspeeds["awp"]);
            $authpts[$val[$i]["authid"]] = (array_key_exists("gc", $val[$i])) ? $authpts[$val[$i]["authid"]] + ($c_val - $i) * (pow(0.98, $val[$i]["gc"]) + $wsw) : $authpts[$val[$i]["authid"]] + ($c_val - $i) * (1 + $wsw);
        }
    }
    foreach ($authpts as $key => $val) {
        $val = round($val, 2);
        foreach ($obj["pro"] as $k2 => $v2) {
            $c_v2 = count($v2);
            for ($i=0; $i<$c_v2; $i++) { 
                if (trim(strtolower($v2[$i]["authid"])) == trim(strtolower($key)))
                    $res = $v2[$i];
            }
        }
        if(isset($res))
            $points[$res["name"]] = $val;
    }
    uasort($points, function($a, $b) {
        if ($a == $b)
            return 0;
        return ($a > $b) ? -1 : 1;
    });
    return $points;
}

1 个答案:

答案 0 :(得分:3)

在循环之前创建一个包含来自$recs的数据的关联数组。在内部循环中,尝试在变量中缓存重复的表达式。并且在添加元素时使用+=来避免两次计算数组表达式。

$recs_assoc = array();
foreach ($recs as $r) {
    $recs_assoc[$r[0]] = $r[1];
}
$authpts = array();
foreach ($obj["pro"] as $key => $val) {
    $wr = $recs_assoc[$key];
    $c_val = count($val);
    for ($i=0; $i<$c_val; $i++) {
        $thisval = $val[$i];
        $authid = $thisval["authid"];
        if (!array_key_exists($authid, $authpts)) {
            $authpts[$authid] = 0;
        }
        $ratio = 0;
        if (strlen($c_wr) > 0) {
            $ratio = comparetime($thisval["time"], $wr);
            $ratio = $ratio[0];
        }
        $rbonus = ($ratio > 0) ? pow($ratio, (2 / $ratio)) : 0;
        $authpts[$authid] += ($c_val - $i) * (1 + $rbonus);
    }
}

如果您将上一个作业更改为:

,则可以删除对array_key_exists的调用
        @$authpts[$authid] += ($c_val - $i) * (1 + $rbonus);

@会抑制通常因增加不存在的元素而导致的警告。它会将元素视为包含0,因此仍然可以获得正确的结果。