Back in the day when I did C programing we used assume statements to make sure the code was healthy. Something like:
aFunction(int hello)
{
assume(hello < 10);
The cool thing about the assume statement is it was defined to be an empty macro for release compiling and a die on false statement on debug compiling. So the developer had all the benefits of an assert statement checking their assumptions without causing unnecessary bugs or affecting performance in
Now that I'm working php I'm looking for a similar mechanism. I currently have my assume statement looking something like this:
define(DEBUG, getenv('debug'));
function assume($a)
{
if (DEBUG && !$a)
{
echo 'ASSUME FAILURE <br />';
echo '<pre>';
print_r(debug_backtrace());
die('<pre>');
}
}
assume($a == $b);
As you can see I set the debug flag in the server settings to remove the actual die statement and such. However a function call is still performed and an if statement is still evaluated. This is not a big deal if it only occurs a few thousand times but as the code get's bigger and as these assumes get put into loops this could have a legitimate affect on performance.
Is there a way to tell the interpreter or opcache (I'm currently using zend opcache included in php 5.5) to ignore these assume statements altogether? or is there another method of handling this problem?
The difference is that the C compiler is optimized and can eliminate blocks of code that are not used. In PHP, assume
is a function call, and the function has to exist.
A couple of solutions. First, you may use assert()
. The assert
function works similar to your own assume
function. If an assertion fails, a defined assertion handler is called. You can easily enable or disable assertions, and if you disable them, the assertion handler is not called at all.
If you want to proceed with your own assume
function, you can still optimize it a little, by declaring the function based on the define:
<?php
define(DEBUG, getenv('debug'));
if (DEBUG) {
function assume($a) {
echo 'ASSUME FAILURE <br />';
echo '<pre>';
echo print_r(debug_backtrace());
die('<pre>');
}
} else {
function assume($x) {}
}
This way, you actually declare assume
as an empty function. The comment by Michael Berkowski confirms my fear that PHP doesn't eliminate the call completely, but at least you save the if
.
Another solution is to call assume a little more complex:
DEBUG && assume($x < 10);
This way, if DEBUG is false, the call is not made at all. This way only the boolean value is evaluated, and no function call is made. Of course, calling it this way is a bit harder and less readable, but I think the savings of not calling a function are much more significant than eliminating an if
.