Performance of default and enum parameters

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Feb 7 23:18:53 UTC 2018


On Wed, Feb 07, 2018 at 11:04:29PM +0000, jmh530 via Digitalmars-d-learn wrote:
[...]
> If check is not passed, I think it depends on how default function
> arguments work. I could imagine that it works in two ways: 1) if you
> call bar(x), then the compiler effectively re-writes it to bar(x,
> true), which would mean that the if statement must run, 2) the
> compiler creates functions int bar(int x) and int bar(int x, bool
> check), where the first has the check optimized away and the second is
> as normal, calling bar(x) means that the optimized one is called.

Default arguments mean precisely that: if you don't specify that
parameter, the compiler inserts the default argument for you. IOW:

	int bar(int x, bool check = true) { ... }
	bar(1);		// rewritten as bar(1, true);


> If check is known at compile-time, I would think that the compiler
> could optimize away the if statement because it is known at
> compile-time which part will be there or not.
[...]

Default arguments are a syntactic construct. They have little to do with
what optimizations are done by the compiler. A function without default
arguments can be optimized the same way as a function with default
arguments.  Whether or not something is optimized away is more dependent
on the optimizer than on the syntax used to write the code.

If you want to know for sure, check the assembly output, e.g., of ldc.
The last time I checked, ldc is able to inline and optimize away even
nested loops (up to a certain complexity), needless to say a simple
boolean if-statement like your example code.  This was in the context of
certain proposed Phobos optimizations, and it was funny because we were
getting strange benchmark results like 0ms for the entire function when
compiled with ldc. Disassembling showed that what actually happened was
that ldc determined that since the return value of the function was
never used, the entire function call could be deleted completely.

In another case, because the function arguments were known at
compile-time, ldc executed the function at compile-time and substituted
the function call with just loading the return value directly into a
register, so the function was never actually called.

Basically, if you use a compiler with an aggressive optimizer like
ldc's, don't waste your time with micro-optimizations. The compiler will
do it for you.  Trying to hand-optimize your code can sometimes backfire
-- the code can become too strange for the optimizer to understand, so
it gives up and ends up *not* optimizing it at all.

In this day and age, the only time you actually need to hand-optimize is
when a profiler has identified real hotspots, and usually the fix is
relatively simple. (And IME, the real hotspots are often NOT where I
predict them to be. So optimizing stuff before I have real data from a
profiler is usually a waste of my time.)


T

-- 
Public parking: euphemism for paid parking. -- Flora


More information about the Digitalmars-d-learn mailing list