Live data from Hacker News

Practices for writing high-performance Go

github.com

71–80 of 102 posts

Re: Practices for writing high-performance Go

#71

Almost none of this is about Go. 80% down they mention some basic stuff about GC, but nothing very specific about the Go GC. Then after that it is back to very basic language-agnostic optimization ideas. I was hoping for more insights about Go specifically.

I've done a Go course a while ago; interestingly enough, at least the first day, it wasn't about Go at all. The trainer basically stated that if you know any curly braces language, you can write Go.

And I think that's the point. The language doesn't get in your way, and it's not any specific language feature that will make your code go fast or slow - unless you abuse it, or use it when you don't need to.

I mean if you're happy with C then by all means; Go isn't claiming to be faster than other languages, not this close to the metal. It's mainly aimed to take away some of the mental overhead you get with C and similar languages. And compile times.

Re: Practices for writing high-performance Go

#72
post #58

any thoughts on whether to use values or pointers to large structs? in practice I haven’t seen any major performance overhead when passing values about.

There is no straight answer to this, so, it depends. I think it's really one of those problems that isn't important yet until you can actively measure a performance issue. Until then, focus on clarity and functionality; it's much easier to measure and optimize code if your code and its intent is clear. Until then, beware of premature optimization.

Re: Practices for writing high-performance Go

#73

Earlier quoted context omitted.

Stack is great, then you will spend more time in runtime.morestack because the Go authors have wisely decided that we are all too dumb to request specific stack sizes and we must rely on copying and doubling stacks larger than 2KiB even if we know in advance that 2KiB is not enough. This compares poorly with native threads where the stacks are dynamically allocated one page at a time without copying and we can specif…

My point is that you should file a Github issue if there isn't one.

Why "should"? Nobody owes the writing of issues.

Re: Practices for writing high-performance Go

#75

Earlier quoted context omitted.

Is there a Github issue for this problem? If not, would you consider filing one? https://github.com/golang/go/issues It should probably explain why one cannot "avoid its global allocator" by using pools and/or stack objects.

Stack is great, then you will spend more time in runtime.morestack because the Go authors have wisely decided that we are all too dumb to request specific stack sizes and we must rely on copying and doubling stacks larger than 2KiB even if we know in advance that 2KiB is not enough. This compares poorly with native threads where the stacks are dynamically allocated one page at a time without copying and we can specif…

The runtime.morestack issue is actually being tracked btw [0]. I'm also getting the impression that you want Go to be another C++, but I don't understand why.

All of your listed issues have additional details and discussions around them. It not "we don't add this stuff because you are too dumb to use it". It's more "we don't know how to add this currently so it would properly interact with other features and be non-confusing". There are some exceptions to this rule (time.Time issue comes to mind) but overall they tend to listen to the developer base. Also, keep in mind that there are also relatively few Core Go developers, so they have to be extremely careful about what they gonna add in the language. It's going to be them who is going to support it in years to come.

As for C++ - yes, nothing beats it in highly optimized cases. And there is nothing wrong with that. The problem is not only writing C++ for those highly optimized cases is an extremely hard task by itself. The problem is finding people who can actually do it with the resulting code which is going to be supportable in the future (I'm not talking about UB, races or memory leaks).

[0]: https://github.com/golang/go/issues/18138

Edit: wording

Re: Practices for writing high-performance Go

#76
post #40

Earlier quoted context omitted.

Disagree. I can write a server in C++ that, with careful thought and a bit of planning, will be able to exploit the resources of the kind of 88-core dual-socket machines that are mainstream today. No amount of planning will allow me to write a Go program that does the same thing on the same machine. Small amounts of concurrency might seem easy in Go but lots of concurrency is hard.

"I can write a server in C++ that, with careful thought and a bit of planning, will be able to exploit the resources of the kind of 88-core dual-socket machines that are mainstream today." This is downvoted grey as I write this, and as someone who has been called a "Go shill" on occasion... it's exactly right. Go is a decent language for writing code in a fairly straightforward manner and getting pretty good performa…

Presumably he was downvoted for responding to “concurrency in Go is easier” with “Disagree. I can get every bit of performance out of an 88 core CPU with C++”. It’s not a coherent counter argument; no one claimed Go was as efficient as C++, only that concurrency is easier.

Re: Practices for writing high-performance Go

#77
post #22

Earlier quoted context omitted.

You're talking a about a very specific scenario, out of the box Go is off course easier than C++ for concurrency. Who by the way runs applications on a 88 core server, why would you so they instead of splitting that into smaller chunks.

You're making a different argument, that one does not need so much vertical scalability, and I might agree, but that doesn't negate the fact that Go has limits of vertical scalability that C++ doesn't face.

The original claim was that concurrency is easier in Go, not that Go has a higher performance ceiling. You are the one making the different argument. :)

Re: Practices for writing high-performance Go

#78
post #34

Earlier quoted context omitted.

I guarantee you the "little bit of planning" you're doing in C++ is far greater than the equivalent planning in Go to avoid the global allocator in your goroutines (i.e., allocate on the stack, use object pools, etc). I'm sure you still won't get to the same performance ceiling that C++ allows, but it doesn't mean "Go is bad at concurrency".

The philosophy of Go, as far as I can tell, is opinionated simplicity. In this way, it is fantastic at concurrency. It gives you a simplified fork in goroutines, a way to safely pass by value or signal between these through channels, and structures like select to psuedo randomly deal with race conditions. That stuff is all awesome! But when you are talking about performance, opinionated simplicity is a bad philosophy…

Your post doesn’t address mine. I gave specific advice for addressing the GP’s issue. It’s much easier to move your allocs out of the hot path in Go than it is to do virtually anything in C++. I’m not claiming Go will compete with C++ on performance, only that his argument isn’t a good reason to write off Go. (I’ve written a lot of both languages).

Re: Practices for writing high-performance Go

#79
post #64

Earlier quoted context omitted.

Honestly with the attitude that the Go authors treat their users I don't know why anyone tries to write high performing code in that language. C++ is there, after all. I work in C++. I'm sometimes surprised at the way C++ treats its users. There seems to be a culture of pre-optimization. It's hard to write the most abstract application code without constantly thinking about performance under the surface. That's baked…

It is a trait inherited from the C culture, although in C it is even worse, micro-optimizing every line of code as it is being written. A C dev would start cold sweating has s/he types virtual , or operator something ().

Actually C programmers frequently use dynamic dispatch - even in the Linux Kernel for example. They just like to be explicit about it.

Re: Practices for writing high-performance Go

#80
post #66
post #40

Earlier quoted context omitted.

"I can write a server in C++ that, with careful thought and a bit of planning, will be able to exploit the resources of the kind of 88-core dual-socket machines that are mainstream today." This is downvoted grey as I write this, and as someone who has been called a "Go shill" on occasion... it's exactly right. Go is a decent language for writing code in a fairly straightforward manner and getting pretty good performa…

How would Rust compare?

Concurrency in Rust is extremely easy, because it safe by design. Just import rayon crate and change iter() to par_iter() [1]. Compiler will point out to problems, e.g. it will not allow to send a type, which cannot be used concurrently, until it will be wrapped by Arc (atomic reference counter).

[1]: https://docs.rs/rayon/1.0.3/rayon/

Post reply on HN