因为 MYSQL 的“SELECT”选择整数和 float 作为字符串,我需要(从 JS)得到的每个响应都在正确的数据模型中 -
- 1 不是“1”,
- 53.2 不是“53.2”,
我创建了这个适用于混合类型 - 数组/对象的递归函数:
private function cast_number(&$mixed) {
if(is_array($mixed)) {
foreach ($mixed as $key => $val)
if (is_numeric($val))
$mixed[$key] = (double)$val;
else if (is_array($val) || is_object($val))
$mixed[$key] = $this->cast_number($val);
} else if(is_object($mixed)) {
foreach ($mixed as $key => $val)
if (is_numeric($val))
$mixed->$key = (double)$val;
else if (is_array($val) || is_object($val))
$mixed->$key = $this->cast_number($val);
}
return $mixed;
}
非常简单的函数 - 如果是数字,则转换成 double ,如果是数组或对象,则递归地进行。
这里一切就绪。
我有两个问题: - 在 6MB 的数据上,大部分用字符串表示的数字花费了 0.5 秒 - 在 200MB 的数据上(是的,我需要它,请不要关注它),它在几分钟(通常是几秒钟)后失败,说它需要超过 4GB 的内存..
- 如何改进此功能? (速度,内存)
- 为什么要花这么长时间?即使是 json_encode,我认为它是一个更大的函数,花费的时间要少得多。
最佳答案
因为强制used to be faster than casting ,我运行这段代码来计算 PHP 7 上的时间:
function getTime($start) {
return round((microtime(true) - $start) * 1000000) / 1000;
}
function mockData($length) {
$data = [];
$i = -1;
while ($i++ < $length) {
$data[$i] = strval(rand(1, 10000) / 100);
}
return $data;
}
$data = mockData(100000);
// Let's check that they are string before
echo gettype($data[0]) . '<br><br>';
$start = microtime(true);
$convertedData = [];
foreach ($data as $key => $value) {
$convertedData[$key] = (double) $value;
}
echo '(double) cast took ' . getTime($start) . ' ms.<br>';
$start = microtime(true);
$convertedData = [];
foreach ($data as $key => $value) {
$convertedData[$key] = 0 + $value;
}
echo 'Coercion took ' . getTime($start) . ' ms.<br>';
我的结果是:
(double) cast took 27.508 ms.
Coercion took 28.789 ms.
结论
因为使用 floatval
(实现字符串到 double 转换的第三种方法)甚至更长,所以没有比使用 PHP 做得更好的了。您要实现的是脚本操作,不应将其用作 Web 应用程序的正常后端操作。
但如果您仍然想这样做,您可以提高 php.ini
文件中的 memory_limit
,as long as you don't use the -1
workaround .
更新
我忘记了一个可能的优化,你应该pass your variable by reference至少执行立即分配:
$start = microtime(true);
foreach ($data as $key => $value) {
$data[$key] = (double) $value;
}
echo getTime($start) . ' ms.<br>';
=> 34.018 毫秒。
$start = microtime(true);
foreach ($data as &$value) {
$value = (double) $value;
}
echo getTime($start) . ' ms.<br>';
=> 17.081 毫秒。
并且显然使用通过引用 进行强制转换会得到更好的结果:
$start = microtime(true);
foreach ($data as &$value) {
$value = 0 + $value;
}
echo getTime($start) . ' ms.<br>';
=> 13.1 毫秒。
关于PHP - 将字符串递归替换为数字需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37908562/