我目前正在优化一个 PHP 应用程序,发现一个函数被调用了大约 10-20k 次,所以我想我应该从那里开始优化:
function keysToLower($obj)
{
if(!is_object($obj) && !is_array($obj)) return $obj;
foreach($obj as $key=>$element)
{
$element=keysToLower($element);
if(is_object($obj))
{
$obj->{strtolower($key)}=$element;
if(!ctype_lower($key)) unset($obj->{$key});
}
else if(is_array($obj) && ctype_upper($key))
{
$obj[strtolower($key)]=$element;
unset($obj[$key]);
}
}
return $obj;
}
大部分时间都花在递归调用上(这在 PHP 中相当慢),但我没有看到任何方法将其转换为循环。
你会怎么办?
这个版本不考虑关联数组,因为我的数据没有关联数组,但比原始版本快了近 10 倍。大部分工作是由 Gumbo 完成的,主要的加速来自于使用引用和创建一个新对象,而不是取消设置旧的键。
function &keysToLower(&$obj)
{
if(is_object($obj))
{
$newobj = (object) array();
foreach ($obj as $key => &$val)
$newobj->{strtolower($key)} = keysToLower($val);
$obj=$newobj;
}
else if(is_array($obj))
foreach($obj as &$value)
keysToLower($value);
return $obj;
}
Foreach
正在使用随后被遍历的内部副本。尝试不使用:
function keysToLower($obj)
{
$type = (int) is_object($obj) - (int) is_array($obj);
if ($type === 0) return $obj;
reset($obj);
while (($key = key($obj)) !== null)
{
$element = keysToLower(current($obj));
switch ($type)
{
case 1:
if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
{
unset($obj->{$key});
$key = $keyLowercase;
}
$obj->{$key} = $element;
break;
case -1:
if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
{
unset($obj[$key]);
$key = $keyLowercase;
}
$obj[$key] = $element;
break;
}
next($obj);
}
return $obj;
}
或者使用引用来避免使用副本:
function &keysToLower(&$obj)
{
$type = (int) is_object($obj) - (int) is_array($obj);
if ($type === 0) return $obj;
foreach ($obj as $key => &$val)
{
$element = keysToLower($val);
switch ($type)
{
case 1:
if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
{
unset($obj->{$key});
$key = $keyLowercase;
}
$obj->{$key} = $element;
break;
case -1:
if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
{
unset($obj[$key]);
$key = $keyLowercase;
}
$obj[$key] = $element;
break;
}
}
return $obj;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)