Live data from Hacker News

Go Optimization Guide

goperf.dev

111–120 of 173 posts

Re: Go Optimization Guide

#111
post #52
post #50

Earlier quoted context omitted.

You never programmed in Go, I assume? Then you have to understand that the type of `pool.Get()` is `any`, the wildcard type in Go. It is a type, and if you want the underlying value, you have to get it out by asserting the correct type. This cannot be solved with generics. There's no way in Java, Rust or C++ to express this either, unless it is a pool for a single type, in which case Go generics indeed could handle t…

> That's what the New function does, isn't it? But that's only run when the pool needs to allocate more space. What GP seems to expect is that sync.Pool() would always return a zeroed structure, just as Golang allocation does. I think Golang's implementation does make sense, as sync.Pool() is clearly an optimization you use when performance is an issue; and in that case you almost certainly want to only initialize pa…

> But that's only run when the pool needs to allocate more space. What GP seems to expect is that sync.Pool() would always return a zeroed structure, just as Golang allocation does.

Not quite that. Imagine I have a pool of buffers with a length and capacity, say when writing code to handle receiving data from the network.

When I put one of those buffers back, I would like the next user of that buffer to get it back emptied. The capacity should stay the same, but the length should be zero.

I think it’s reasonable to have a callback to do this. One, it doesn’t force every consumer of the pool to have to remember themselves; it’s now a guarantee of the system itself. Two, it’s not much work but it does prevent me from re-emptying freshly-allocated items (in this case reinitialzing is fast, but in some cases it may not be).

This also should be an optional callback since there are many cases where you don’t want any form of object reset.

Re: Go Optimization Guide

#112
post #107

Earlier quoted context omitted.

> I don't get what else one expects when pooling pointers to a type? As seen in your previous comment, the expectation is that the zero value will always be returned: "What GP seems to expect is that sync.Pool() would always return a zeroed structure, just as Golang allocation does." To which you offered a guarantee. > Pool.Put() or Pool.Get() then must zero its contents. Right. That is the solution (as was also echo…

> And, unfortunately, doesn't even get the generic constraints right, as demonstrated with the int and bool examples. If those constraints don't hold (like you say) it should manifest as runtime panic, no? > What GP seems to expect is that sync.Pool() would always return a zeroed structure Ah, well. You gots to be careful when Pool ing addresses. > But you completely forgot to do it, which questions what your code wa…

> If those constraints don't hold (like you say) it should manifest as runtime panic, no?

No. Your int and bool pools run just fine – I can't imagine you would have posted the code if it panicked – but are not correct.

> I did not forget?

Then your guarantee is bunk: "One could define a new "Pool[T]" type (extending sync.Pool) to get these guarantees:" Why are you making claims you won't stand behind?

Re: Go Optimization Guide

#113
post #112

Earlier quoted context omitted.

> And, unfortunately, doesn't even get the generic constraints right, as demonstrated with the int and bool examples. If those constraints don't hold (like you say) it should manifest as runtime panic, no? > What GP seems to expect is that sync.Pool() would always return a zeroed structure Ah, well. You gots to be careful when Pool ing addresses. > But you completely forgot to do it, which questions what your code wa…

> If those constraints don't hold (like you say) it should manifest as runtime panic, no? No. Your int and bool pools run just fine – I can't imagine you would have posted the code if it panicked – but are not correct. > I did not forget? Then your guarantee is bunk: "One could define a new "Pool[T]" type (extending sync.Pool) to get these guarantees:" Why are you making claims you won't stand behind?

It was a blueprint. Embedding and typedefs are ways to implement these guarantees. And of course, writing a generic pool library is not what I was after.

> but are not correct.

I don't follow what you're saying. You asserted, "And, unfortunately, doesn't even get the generic constraints right, as demonstrated with the int and bool examples." What does it even mean? I guess, this bikeshed has been so thoroughly built that the discussion points aren't even getting through.

Re: Go Optimization Guide

#114
post #112

Earlier quoted context omitted.

> If those constraints don't hold (like you say) it should manifest as runtime panic, no? No. Your int and bool pools run just fine – I can't imagine you would have posted the code if it panicked – but are not correct. > I did not forget? Then your guarantee is bunk: "One could define a new "Pool[T]" type (extending sync.Pool) to get these guarantees:" Why are you making claims you won't stand behind?

It was a blueprint. Embedding and typedefs are ways to implement these guarantees. And of course, writing a generic pool library is not what I was after. > but are not correct. I don't follow what you're saying. You asserted, "And, unfortunately, doesn't even get the generic constraints right, as demonstrated with the int and bool examples." What does it even mean? I guess, this bikeshed has been so thoroughly built…

[deleted]

Re: Go Optimization Guide

#115
post #112

Earlier quoted context omitted.

> If those constraints don't hold (like you say) it should manifest as runtime panic, no? No. Your int and bool pools run just fine – I can't imagine you would have posted the code if it panicked – but are not correct. > I did not forget? Then your guarantee is bunk: "One could define a new "Pool[T]" type (extending sync.Pool) to get these guarantees:" Why are you making claims you won't stand behind?

It was a blueprint. Embedding and typedefs are ways to implement these guarantees. And of course, writing a generic pool library is not what I was after. > but are not correct. I don't follow what you're saying. You asserted, "And, unfortunately, doesn't even get the generic constraints right, as demonstrated with the int and bool examples." What does it even mean? I guess, this bikeshed has been so thoroughly built…

> What does it even mean?

Values are copied in Go. Your code will function, but it won't work.

You've left it up to the user of the pool to not screw things up. Which is okay to some degree, but sync.Pool already does that alone, so what is your code for?

Re: Go Optimization Guide

#116
post #115

Earlier quoted context omitted.

It was a blueprint. Embedding and typedefs are ways to implement these guarantees. And of course, writing a generic pool library is not what I was after. > but are not correct. I don't follow what you're saying. You asserted, "And, unfortunately, doesn't even get the generic constraints right, as demonstrated with the int and bool examples." What does it even mean? I guess, this bikeshed has been so thoroughly built…

> What does it even mean? Values are copied in Go. Your code will function, but it won't work. You've left it up to the user of the pool to not screw things up. Which is okay to some degree, but sync.Pool already does that alone, so what is your code for?

> Values are copied in Go

Gotcha. Thanks for clearing it up.

> so what is your code for?

If that's not rhetorical, then the code was to demonstrate that sync.Pool could be "extended" with typedefs/embeds + custom logic. Whether it got pooling itself right was not the intended focus (as shown by the fact that it created int & bool pools).

Re: Go Optimization Guide

#117
post #115

Earlier quoted context omitted.

> What does it even mean? Values are copied in Go. Your code will function, but it won't work. You've left it up to the user of the pool to not screw things up. Which is okay to some degree, but sync.Pool already does that alone, so what is your code for?

> Values are copied in Go Gotcha. Thanks for clearing it up. > so what is your code for? If that's not rhetorical, then the code was to demonstrate that sync.Pool could be "extended" with typedefs/embeds + custom logic. Whether it got pooling itself right was not the intended focus (as shown by the fact that it created int & bool pools).

> then the code was to demonstrate that sync.Pool could be "extended" with other types and custom logic.

Wherein lies the aforementioned guarantee? The code guarantees neither the ask (zero values) nor even proper usage if you somehow didn't read what you quoted and thought that some kind of type safety was the guarantee being offered.

Furthermore, who, exactly, do you think would be familiar enough with Go to get all the other things right that you left out but be unaware of that standard, widely used feature?

Re: Go Optimization Guide

#118
post #65

"Although the struct Data contains a [1024]int array, which is 4 KB (assuming int is 4 bytes on the architecture used)" Huh,what? I mean, who uses 32b architecture by default?

Most C/C++ compilers have 32b int on 64b arch. Maybe the confusion comes from that.

Also it would be 4KiB not 4KB.

Re: Go Optimization Guide

#119
post #117

Earlier quoted context omitted.

> Values are copied in Go Gotcha. Thanks for clearing it up. > so what is your code for? If that's not rhetorical, then the code was to demonstrate that sync.Pool could be "extended" with typedefs/embeds + custom logic. Whether it got pooling itself right was not the intended focus (as shown by the fact that it created int & bool pools).

> then the code was to demonstrate that sync.Pool could be "extended" with other types and custom logic. Wherein lies the aforementioned guarantee? The code guarantees neither the ask (zero values) nor even proper usage if you somehow didn't read what you quoted and thought that some kind of type safety was the guarantee being offered. Furthermore, who, exactly, do you think would be familiar enough with Go to get al…

> Wherein lies the aforementioned guarantee?

I think you should re-read what I wrote. You seem to be upset that I did not solve everyone's problem with sync.Pool with my 10 liner (when I claimed no such thing).

  One could define a new "Pool[T]" type (extending sync.Pool) to get these guarantees
Meant... One could define / extend sync.Pool to get those guarantees [for their custom types] ... Followed by an example for int & bool types (which are copied around, so pooling is ineffective like you say, but my intention was to show how sync.Pool could be extended, and nothing much else).

Re: Go Optimization Guide

#120
post #66
post #64

Earlier quoted context omitted.

> What GP seems to expect is that sync.Pool() would always return a zeroed structure Might be, but that's a design decision that has nothing to do with type or generics, isn't it? You seem to refer to a function to drain the pool, which is not needed, and frankly, rather unusual. > It's typed the way Python is typed Not in the slightest. > "if it compiles there's a good chance it's correct" If you want to compare it…

> Not in the slightest. You know, it's this kind of comment on USENET forums which prompted the creation of StackOverflow. It's not curious and adds nothing to the discussion. I like Go and use it extensively; and I like having the option to fall back to the `any` type. But it's simply a fact that using the `any` type means that certain properties of the program can't be checked at compile time, in the same way that…

> But it's simply a fact that using the `any` type means that certain properties of the program can't be checked at compile time

Yes, structural typing removes the ability to check certain properties at compile-time. That doesn't make it typed like Python, though.

Post reply on HN