Returning int instead of bool can actually make things _less_ efficient
Stewart Gordon
smjg_1998 at yahoo.com
Thu Dec 7 09:38:44 PST 2006
There's been quite some debate over the fact that some functions in
Phobos, including Object.opEquals, have return types of int, even though
their returns are semantically boolean.
In some instances, it can help, if the efficiency lies in the ability to
return a value other than 0 or 1 and avoid the overhead of converting
the value to a boolean.
But in some cases, no efficiency can be gained by this. Indeed,
opEquals appears to be a prime example of this. While a "not equals"
function can gain efficiency by subtracting one value from the other and
just returning the result, an "equals" function cannot.
If a function declared with a bool return type tries to return numbers
other than 0 or 1, then the function must internally convert the value
to a boolean. However, if the compiler, while compiling a function
declared to return bool, discovers that it never tries to return
anything that isn't 0 or 1 - then there's no point generating the
conversion code.
Moreover, if the compiler knows that a given variable or subexpression
is boolean, then I can see a potential for the compiler to use this
knowledge to optimise certain expressions/code forms. For example, of
these, which is more efficient?
b ? 43 : 42 or 42 + b
b ? 64 : 0 or b << 6
b ? 32 : 16 or 16 << b
!b or 1 - b
b & c or b * c
b & !c or b > c
!b | c or b <= c
If the compiler knows that b and c are boolean, it could optimise one
form to the other, whichever is quicker on the processor for which the
code is being compiled. The last three could also work with && and ||,
if the right operand is just a variable or something that can be reduced
to one at compile-time.
Consider also the bit-twiddling operations common in programs that
interface certain OS APIs. Could these be more efficient with the
optimisation of operations on booleans? (OK, so _extracting_ a bit is
an operation that could benefit from the added efficiency of returning
an int or whatever, but that's aside.)
In both library and application code, there will be some divide between
programmers who:
(a) have every function with a semantically boolean return value
returning bool
(b) just use int to pass booleans around, having not got into using bool
since migrating from C
(c) will consider each function and ask themselves which return type
will work best from an efficiency POV
Programmers of kind (a), and to some extent (c), will sometimes want to
make a function X return bool, but find themselves calling a third-party
function Y that returns an int, albeit with boolean semantics. If the
implementation of Y never tries to return anything but 0 or 1, and the
compiler can readily determine this fact, then nothing has been gained
by returning an int. The creator of X will have to either change the
return type to int, still losing the optimisation potential of booleans
further up the call stack, or put up with the extra instructions there
and then to convert the int to a bool.
In conclusion....
If performance is a concern, and a given function could save a few
instructions by returning a general integer rather than always returning
0 or 1, then it's quite sensible to return an int. (For libraries/APIs
that are likely to have more than one implementation, the question is
whether an implementation of the given function could feasibly be made
more efficient in this way - and then if it can, it should.) If OTOH,
any feasible implementation would be just as efficient if it returned
only 0 or 1, then it makes most sense to give it a return type of bool.
Stewart.
More information about the Digitalmars-d
mailing list