Live data from Hacker News

Go hits the concurrency nail on the head

eli.thegreenplace.net

171–180 of 318 posts

Re: Go hits the concurrency nail on the head

#171

Its fairly interesting that this article doesn't mention actors, futures/promises and async/await style co-routines which are all extremely available in all of the major languages available today and broadly used (with the possible exception of golang). Frankly, I think the concurrency story is one of the weaknesses of golang. Contrary to what this article says you cannot stop thinking about concurrency in your code…

All of those interfaces are trivial to implement in Go precisely because Go implements a much stronger abstraction. By contrast, if you only have those other abstractions you're quite limited in how you can structure your code. (You might not realize how limited you are, however, if those are your only options.)

As the article says, most languages settle for those interfaces because they can mostly be implemented as libraries with minimal refactoring of the existing implementations and their execution model.

They have their uses but they're not universal enough. If you think actors, futures, and async/await are so great, imagine having to write every single function invocation in that manner. It would be unimaginable outside of some special-purpose declarative DSL. By contrast, the concept of a thread--linear flow of logical execution of statements and expressions--is fundamental to programming. Even in functional languages with lazy evaluation or automagic parallelism. It's a basic building block similar to functions. And much like functions, it's incredibly useful to be able to easily compose those blocks, which is where channels and message passing come into the equation. One way to compose them is with actor and future interfaces, but that's not the only way and not always the most appropriate way.

Threads ended up with a bad name because of (1) performance and (2) races, but that conflates the abstract concept of a thread--a construct that encapsulates the state of recursive function calls--with particular implementations. Goroutines are threads, pure and simple, but [mostly] without all the baggage of traditional implementations. (That they can be scheduled to execute in parallel complicates the construct but also makes them useful for the same reasons traditional OS threading constructs were predominately used, except with much less of the baggage.)

Re: Go hits the concurrency nail on the head

#172
post #94

Earlier quoted context omitted.

True, but Go and Erlang don't occupy the same niche. Go is imperative, while Erlang is mostly functional. Go is AOT (ahead-of-time) compiled, while Erlang runs on a VM. Go is statically typed, while Erlang is dynamically typed (I know about Dializer). Go concurrency primitives are designed to coordinate goroutines living in the same process, while Erlang concurrency primitives are designed to coordinate Erlang "proce…

Erlang is AOT, the vm reads compiled and optimized bytecode.

You're right. I oversimplified a bit too much.

I should have write: Go produces native binaries, while Erlang runs on a VM.

Re: Go hits the concurrency nail on the head

#173

Go concurrency is just threads. It's a particularly idiosyncratic userland implementation of them. There are two claims here I'd like to unpack further: 1. "I've measured goroutine switching time to be ~170 ns on my machine, 10x faster than thread switching time." This is because of the lack of switchto support in the Linux kernel, not because of any fundamental difference between threads and goroutines. A Google eng…

Nothing you're saying is wrong, but your perspective is totally off. For someone experienced with C++, or say, Rust (ahem), obviously Go is a bit backwards when it comes to concurrency and race conditions. Obviously you can mimic go's goroutine stacks, obviously you can obtain fast thread switching. But Go isn't targeting C++ or Rust, and it's not targeting the domains those languages are best at (although admittedly…

> but your perspective is totally off.

Well, his perspective is well known in all Go threads on HN and this is not only my opinion (look here [1]). He is repeating the same things[2] again[3] and again[4] and again. About M:N in Go, about why Go is worse because it doesn't have generational GC but when asked if he reached to Go team about that there is no response. If you look at his comments from last month you will see how much downplaying of Go is there + other languages. It seems that he only praise one language (ahem) in his comments.

1. https://news.ycombinator.com/item?id=17886153

2. https://news.ycombinator.com/item?id=18101986

3. https://news.ycombinator.com/item?id=17886144

4. https://news.ycombinator.com/item?id=17886122

Re: Go hits the concurrency nail on the head

#175

Go concurrency is just threads. It's a particularly idiosyncratic userland implementation of them. There are two claims here I'd like to unpack further: 1. "I've measured goroutine switching time to be ~170 ns on my machine, 10x faster than thread switching time." This is because of the lack of switchto support in the Linux kernel, not because of any fundamental difference between threads and goroutines. A Google eng…

> Goroutines are threads. So the idea the "Go has eliminated the distinction between synchronous and asynchronous code" is only vacuously true, because in Go, everything is synchronous.

Abstractly, I agree, but practically the distinction is important. In Go you don't have to use a frustrating async interface to get decent performance. You don't have to manage a threadpool or other tricks. You pretty much get the threadlike interface you want to use without the difficulty.

Re: Go hits the concurrency nail on the head

#176
post #69

Earlier quoted context omitted.

Go doesn’t need a VM. That’s key. You get good concurrency with an easy to deploy binary that can target the major chips.

That's a good point. Modern programming languages are all pretty big and complex and whenever someone tries to nail down " this is why it's good/popular" there always seem to be other significant factors that got missed. After all, if it were just one factor that leads to programming language popularity, we could design the Next Big Language by just following that recipe! In the case of Go, I can imagine many of its…

I like Go because everything is super simple. From dependency management to unit testing to performance profiling to its build/deploy story, everything just works. I don't need to learn a new configuration language and project configuration format and complex dependency management system just to build my project. I don't need to pick a unit test framework and test runner. I don't need to figure out how to wire said framework / test runner into my build tooling. I don't need to figure out how to ship my app along with its dependencies or make sure that my deployment target has the right version of a VM installed. I don't even need to worry about learning a new IDE. I could keep going, but it's things like this that matter to me even more than the language itself.

Re: Go hits the concurrency nail on the head

#177

Go concurrency is just threads. It's a particularly idiosyncratic userland implementation of them. There are two claims here I'd like to unpack further: 1. "I've measured goroutine switching time to be ~170 ns on my machine, 10x faster than thread switching time." This is because of the lack of switchto support in the Linux kernel, not because of any fundamental difference between threads and goroutines. A Google eng…

> Goroutines are threads. So the idea the "Go has eliminated the distinction between synchronous and asynchronous code" is only vacuously true, because in Go, everything is synchronous. Abstractly, I agree, but practically the distinction is important. In Go you don't have to use a frustrating async interface to get decent performance. You don't have to manage a threadpool or other tricks. You pretty much get the thr…

Let's be clear: the one-OS-thread-per-connection model does yield decent performance. We used to call async I/O "solving the C10K problem"—i.e. serving 10,000 clients simultaneously.

I'm speaking from experience here, having tried to implement M:N and abandoning it in favor of 1:1, which yielded better performance. Can M:N yield better performance than 1:1? Sure, in some circumstances. But I think that, ideally, we should be striving for 1:1 everywhere.

Re: Go hits the concurrency nail on the head

#178
post #162

Earlier quoted context omitted.

The point is that Erlang (like Java etc) needs a runtime, Go doesn't.

Every programming language has a runtime, even Assembly if the CPU is micro-coded. How do you think that the GC, go-routine scheduler, cgo marshaling get managed?

I thought it was pretty obvious that the OP was using "runtime" to refer to an external interpreter program. The significance being the simplicity of deployment.

Re: Go hits the concurrency nail on the head

#179
post #125

Go concurrency is just threads. It's a particularly idiosyncratic userland implementation of them. There are two claims here I'd like to unpack further: 1. "I've measured goroutine switching time to be ~170 ns on my machine, 10x faster than thread switching time." This is because of the lack of switchto support in the Linux kernel, not because of any fundamental difference between threads and goroutines. A Google eng…

> Goroutines are threads This is a thing I have to continually remind newer engs that are using Go. Goroutines have exactly the same memory observability / race conditions / need for locking/etc as any threaded language. Every race bug that exists in e.g. Java also exists in Go. The only real difference for most code is that it pushes you very hard to use channels directly , as they're the only type-safe option. Ther…

> The only real difference for most code is that it pushes you very hard to use channels directly, as they're the only type-safe option.

It is, but it is also a super important difference: Go provides inbuilt libraries to make inter-thread synchronization more bearable for the average user, e.g. channels and waitgroups. These are lot harder to misuse than bare mutexes and condition variables. Since those are not available in other languages and are too complex for most users to implement them on their own (especially when select{} is required), the solutions there often end up more error-prone.

Re: Go hits the concurrency nail on the head

#180

Go concurrency is just threads. It's a particularly idiosyncratic userland implementation of them. There are two claims here I'd like to unpack further: 1. "I've measured goroutine switching time to be ~170 ns on my machine, 10x faster than thread switching time." This is because of the lack of switchto support in the Linux kernel, not because of any fundamental difference between threads and goroutines. A Google eng…

I'm trying to find out what you mean by "switchto support". Do you have a link?
Post reply on HN