logoalt Hacker News

Allocating on the Stack

98 pointsby spaceytoday at 4:34 PM43 commentsview on HN

Comments

matthewaveryusatoday at 10:10 PM

It's kind of like the small string optimization you see in C++[1] where all the string metadata to account for heap pointer, size and capacity is union'ed with char*. Getting the stack allocation doesn't costs extra memory, but does cost a bit check. Not sure if slices in go use the same method. 32 bytes is a lot so maybe they fattened slice representations a bit to get a bit more bang for your buck?

[1] https://github.com/elliotgoodrich/SSO-23

OptionOfTtoday at 9:14 PM

> ... > On the third loop iteration, the backing store of size 2 is full. append again has to allocate a new backing store, this time of size 4. The old backing store of size 2 is now garbage.

Correct me if I'm wrong, but isn't this a worst-case scenario? realloc can, iirc, extend in place. Your original pointer is still invalid then, but no copy is needed then.

Unless I'm missing something?

Equally, what happens to the ordering of variables on the stack? Is this new one pushed as the last one? Or is there space kept open?

E.g.:

    var tasks []task
    var other_var int
show 2 replies
nasretdinovtoday at 6:41 PM

Nice to see common and natural patterns to have their performance improved. Theoretically appending to a slice would be possible to handle with just stack growth, but that would require having large gaps between goroutine stacks and mapping them lazily upon access instead of moving goroutines to the new contiguous blocks as it's implemented right now. But given how many questionable changes it requires from runtime it's certainly not going to happen :)

show 1 reply
HarHarVeryFunnytoday at 6:21 PM

This article is about Go, but I wonder how many C/C++ developers realize that you've always had the ability to allocate on the stack using alloca() rather than malloc().

Of course use cases are limited (variable length buffers/strings, etc) since the lifetime of anything on the stack has to match the lifetime of the stack frame (i.e the calling function), but it's super fast since it's just bumping up the stack pointer.

show 7 replies
csjhtoday at 8:34 PM

Optimizations like these are so cool. I love seeing higher level languages take advantage of their high level-ness

show 1 reply
anematodetoday at 6:45 PM

Awesome stuff! Does Go have profile-guided optimization? I'm wondering whether a profile could hint to the compiler how large to make the pre-reserved stack space.

show 1 reply
bertylicioustoday at 6:34 PM

Nice! That's (seems) so simple yet also so very effective. Shouldn't other memory-managed languages be able to profit from this as well?

show 2 replies
lstoddtoday at 7:39 PM

I read that as "Allocating on the Slack" and immediately came up with three ways how to do that.

zabzonktoday at 6:53 PM

alloca() is not part of the C++ standard, and I can't imagine how it could used safely in a C++ environment

mwkaufmatoday at 7:08 PM

If I had a nickel for every article about avoiding implicit boxing in gc-heap languages...

show 1 reply