Because MYSQL's "SELECT" selects integers and floats as strings, and I need every response I get (from JS) to be in a correct data model -
- 1 not "1",
- 53.2 not "53.2",
I created this recursive function that works on mixed type - array/object:
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;
}
Pretty simple function - if is number, cast double, if is array or object, go over recursivly.
Everything here is in place.
I have two problems with this: - On 6MB of data, of mostly numbers that are represented as strings it took 0.5 seconds - On 200MB of data (yes, I need it, please don't focus on it), it failed after a couple of minutes (usually seconds), saying it needs more than 4GB of memory..
- How can I improve this function? (Speed, Memory)
- Why is it taking so long? even json_encode, that I would think is a bigger function takes much less time..
Because coercion used to be faster than casting, I ran this code to calculate timings on PHP 7 :
And my results are :
CONCLUSION
Since using
floatval
(a third way to achieve string to double conversion) is even longer, you can't do better than that with PHP. What you're trying to achieve is a scripting operation, it shouldn't be used as a normal back-end operation for a web application.But if you still want to do that, you can higher your
memory_limit
inside yourphp.ini
file, as long as you don't use the-1
workaround.UPDATE
I forgot one possible optimization, you should pass your variable by reference to at least execute immediate assignation :
=> 34.018 ms.
=> 17.081 ms.
And apparently using coercion with by reference gives even better results :
=> 13.1 ms.