因为mysql的“select”选择整数和浮点数作为字符串,我需要(从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;
}

非常简单的函数-如果是数字,强制双精度,如果是数组或对象,递归遍历。
这里的一切都准备好了。
我有两个问题:
-在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(实现字符串到双精度转换的第三种方法)的时间甚至更长,因此使用php做不到比这更好的事情。您要实现的是一个脚本操作,它不应该用作web应用程序的常规后端操作。
但如果你还想这么做,你可以在memory_limit文件中提高php.inias 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毫秒。

10-08 13:28
查看更多