EDIT: Disregard this, invalid test. Iterating 1M times instead of 1k irons out the wrinkles.

Ever wondered whether it's faster to directly cast a variable versus invoke a casting function in PHP?

I wondered, so I wrote a script that calls (bool) $int 1000 times, then invokes boolval($int) 1000 times. It turns out that boolval() is between 15% and 250% faster than an explicit cast.

I'll bet the same is true for intval(), floatval(), and strval().

#PHP

@ossobuffo You most certainly did something incorrectly when testing. Assuming `boolval()` is using a fully-qualified name (when in a namespace) both should have the same performance, since PHP will optimize `boolval()` into `(bool)`. If not, the explicit cast should be faster.
@ossobuffo Please see https://tideways.com/profiler/blog/how-we-use-hyperfine-to-measure-php-engine-performance from @edorian for insight on how to correctly (micro)benchmark PHP.
How we use hyperfine to measure PHP Engine performance

One of our recurring jobs at Tideways is to ensure that all of our instrumentation works with new and upcoming PHP versions. For us, "working" doesn’t just mean that the results are correct, but that your PHP extension is fast, gathering insights for our customers with a minimal performance overhead. While we have a comprehensive automated test suite, especially for new [...]

Tideways

@timwolla Weird. This was in a non-namespaced script:
```
$test_me = 1;

print "Cast as boolean:\n";
$time = hrtime(true);
for ($i = 0; $i < 1000; $i++) {
$tested = (bool) $test_me;
}
$cast_elapsed = hrtime(true) - $time;
print "1000 casts in $cast_elapsed nanoseconds.\n";

print "Call boolval():\n";
$time = hrtime(true);
for ($i = 0; $i < 1000; $i++) {
$tested = boolval($test_me);
}
$func_elapsed = hrtime(true) - $time;
print "1000 invocations in $func_elapsed nanoseconds.\n";
```

@ossobuffo That's *way* to little iterations. My i7-1365U does the 1000 iterations in roughly 4 microseconds, all kinds of system jitter will affect the results.

Try aiming for at least 100ms runtime of the fastest test (preferably more).

@ossobuffo Also when running multiple tests within the same process, they don't start from an “equal state”, which might bias the results towards the first or last of the tests. By simply reordering the two tests in your example, I get the reverse result.
@timwolla You're right. I upped it to 1M iterations, and it evened out, with directly casting coming out ahead by less than 0.01% on average.

@ossobuffo And please also keep in mind: The PHP engine evolves. What might be true today, might no longer be true tomorrow. New optimizations are being added in every PHP version.

https://phpc.social/@pollita/114522260863354986

Sara Golemon (@[email protected])

"""Checking whether an array is empty with a strict comparison against the empty array is a common pattern in PHP. A GitHub search for "=== []" language:PHP reveals 44k hits. From the set of !$a, count($a) === 0, empty($a) and $a === [] it however is also the slowest option.""" https://github.com/php/php-src/pull/18571 This is a great example of how you should write whatever you find most readable and maintainable, and let us worry about efficiency. Wtih this PR, the "slow" approach becomes a "fast" one.

PHP Community on Mastodon
@ossobuffo i was suspect to begin with. i've seen you updated the post and i've been through this thread. the reason it was suspect from the start for me is boolval() no matter at what stage the optimisation happens... it had to stop and think about optimising it and that is time. mathematically speaking its only possible for it to be almost as good as a raw cast. worst case it does zero opts and boolval() ends up being multiple extra jmps to get to the same point of doing the transform later.