On 9/20/18 1:58 PM, Adam D. Ruppe wrote:
On Thursday, 20 September 2018 at 17:14:12 UTC, Steven Schveighoffer wrote:
I don't know how a performance problem can occur on an error being
thrown anyway -- the process is about to end.
Walter's objection was code size - it would throw stuff out of cache
lines, even if it doesn't need to actually run.
So like this line:
int[] a;
a = a[1 .. $];
With no bounds checking is just
inc a.ptr;
but with bounds checking it becomes something more like
mov ecx, a.length
cmp ecx, 1 // in other words, if length >= offset
jae proceed
push line
push file
call d_arraybounds // throws the error
proceed:
inc a.ptr
Now, what my patch did was just, right before push line, it inserted
"push length; push offset;". I believe this to be trivial since they are
already loaded in registers or immediates and thus just a couple bytes
for those instructions, but Walter (as I recall, this was a while ago
and I didn't look up his exact words when writing this) said even a
couple bytes are important for such a common operation as it throws off
the L1 caches. I never got around to actually measuring the performance
impact to prove one way or another.
But... even if that is a problem, dmd -O will usually rearrange that to
avoid the jump on the in-bounds case, and I'm sure ldc/gdc do too,
sooooo the extra pushes' instruction bytes are off the main execution
path anyway and thus shouldn't waste cache space.
idk though. regardless, to me, the extra info is *well* worth the cost
anyway.
Sounds like a case of premature optimization at best.
Besides, if it is a performance issue, you aren't doing bounds checks on
every slice/index anyway. I know in iopipe, to squeeze out every bit of
performance, I avoid bounds checks when I know from previous asserts the
bounds are correct.
-Steve