On Monday, 4 August 2014 at 03:22:51 UTC, Andrei Alexandrescu
wrote:
On 8/3/14, 6:59 PM, David Bregman wrote:
w.r.t the one question about performance justification: I'm not
necessarily asking for research papers and measurements, but
based on
these threads I'm not aware that there is any justification at
all. For
all I know this is all based on a wild guess that it will help
performance "a lot", like someone who optimizes without
profiling first.
That certainly isn't enough to justify code breakage and
massive UB
injection, is it? I hope we can agree on that much at least!
I think at this point (without more data) a bit of trust in
one's experience would be needed. I've worked on performance on
and off for years, and so has Walter. We have plenty of war
stories that inform our expertise in the matter, including
weird stuff like "swap these two enum values and you'll get a
massive performance regressions although code is correct either
way".
I draw from numerous concrete cases that the right/wrong
optimization at the right/wrong place may as well be the
difference between winning and losing. Consider the recent php
engine that gets within 20% of hhvm; heck, I know where to go
to make hhvm 20% slower with 50 lines of code (compare at 2M+).
Conversely, gaining those 20% were months multiplied by
Facebook's best engineers.
Efficiency is hard to come by and easy to waste. I consider
Walter's take on "assert" a modern, refreshing take on an old
pattern that nicely preserves its spirit, and a good
opportunity and differential advantage for D. If anything,
these long threads have strengthened that belief. It has also
clarified to me that:
(a) We must make sure we don't transform @safe code into unsafe
code; in the first approximation that may simply mean assert()
has no special meaning in release mode. Also bounds checking
would need to probably be not elided by assert. I consider
these challenging but in good, gainful ways.
(b) Deployment of optimizations must be carefully staggered and
documented.
Andrei
First of all, thank you for the reply.
I agree with nearly everything you say. I also have significant
experience with code optimization. I greatly enjoyed the talk you
gave on C++ optimization, partly because it validated what I've
spent so much of my own efforts doing.
I think we reach different conclusions from our experience
though, my feeling is that typical asserts are unlikely to
contain much info that can give a speedup.
This is not to say that the compiler can't be helped by extra
information, on the contrary I wholeheartedly believe it can.
However I would guess this will usually require the asserts to be
specifically written for that purpose, using inside knowledge
about the kinds of information the optimizer is capable of using.
In the end there isn't a substitute for measurement, so if we
rely on experience we're both just guessing. Is it really
justified to say that we're going to break stuff on a hunch it'll
help performance? Considering the downsides to reusing existing
asserts, what if you're wrong about performance?
If new, specialized asserts need to be written anyways, we might
as well use a new keyword and avoid all the downsides,
essentially giving the best of both worlds.
Also, I'm still curious about how you are evaluating the
performance tradeoff in the first place, or do you even see it as
a tradeoff? Is your estimation of the downside so small that any
performance increase at all is sufficient to justify semantic
change, UB injection and code breakage? If so then I see why you
treat it as a forgone conclusion, certainly in a large enough
codebase there will be some asserts here and there that allow you
to shave off some instructions.