当我将以下代码附加到我的脚本时,我的页面加载从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;
}
答案 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,因此仍然可以获得正确的结果。