How to deal with `undefined` buffers in ReleaseSafe mode

I’d really like to use ReleaseSafe builds by default, but I keep finding them unreasonably slow. A common source of slowdowns is var large_buf: [N]u8 = undefined. If you have something like that in the hot path, it has meaningful impact. I’ve seen some other thread that memset is not actually as far as it should be, so that’s one angle to tackle, but I’d possibly like to opt out of the memset. Is there a way to avoid this, while still keeping all the other runtime checks in the function?

Yeah it’s called @setRuntimeSafety

1 Like

I know about that, but I’m not sure how to use it in my case. I want the buffer initialization to not trigger the memset, but I want buffer usage to trigger bound checks. Can I turn it back on in the middle of a block? Maybe I should just try that.

Out of curiosity how large N is causing you issues here, and how much of a performance impact does it have?

You can do this:

var buffer: [2048]u8 = blk: {
   @setRuntimeSafety(false);
   break :blk undefined;
};

...
3 Likes

The last case I was investigating was 4KB buffer, but it was allocated on stack in a function that was called close to 100K times per second. Moving the buffer out of stack gained around 8% of my benchmark.

To be fair on this it may also be sensible to move the buffer up the stack a function or two. I appreciate that’s not always sensible, but it’s a somewhat idiomatic pattern for this kind of thing.

It’s so common though, 4KB is MAX_PATH a lot of the time. This feels like an interesting performance footgun others may hit.

2 Likes