Hacker News new | ask | show | jobs
by neonsunset 700 days ago
This sounds rather crazy and unrealistic, as C# with its task system and threadpool implementation is strictly better at massively concurrent and parallel applications.

Go in general is a poor, bad language with unsound type system, significantly higher amount of footguns and much worse throughput scaling than .NET.

.NET truly is in “casting pearls before swine” predicament if that’s how some of its users see it.

Note that if you look at GitHub statistics - Go has already won popularity-wise because it’s not the technical merit that matters nowadays but “vibes”, which is to say no amount of bullying is sufficient until Go community stops damaging technical landscape.

1 comments

You're not really making a lot of argumentation to back up your claims. C#'s TPL is ok, but it comes with a massive overhead compared to Goroutines where you can have millions of concurrent threads running at the same time, which is just immensely useful when you're dealing with lots and lots of data. Like gathering solar plant data from millions of inverters. On top of that Go comes with build in channels to ensure safe synchronization between your Goroutines. It's not that you cannot write concurrent code in C#, but to do so will involve a higher level of complexity as well as a much higher cost in memory usage and the risk of encountering deadlocks.

For us the major advantage is that it's much more efficient to spread out the computation on multiple CPU's rather than relying on OS or thread pool threads while also lowering the risk of someone writing a bottleneck when they are coding on a thursday afternoon after a day of horrible meetings.

> GitHub statistics

I think Github statistics are meaningless. My github repository is 100% rust. I very rarely use Rust professionally. In fact, I've done precisely one proof of concept before we decided it was too much trouble to adopt it instead of our C++. This may change in the future if the Rust "community" matures. In any case I mostly look at job "statistics" for my area of the world and while Go has been adopted at some of the places I might want to work, it's still a drop in the ocean of java/c#/php/python.

> C#'s TPL is ok, but it comes with a massive overhead compared to Goroutines

The only possible way to make this statement with confidence is never measuring the overhead of tasks and goroutines. Tasks are lighter than goroutines, especially memory-wise. Don't trust me? Write any sample code you consider representative. Try spawning one million tasks and then one million goroutines, look at memory consumption and execution time. Surely the results will be as you say, right?

Also, .NET has channels out of box and they are being used where they make sense (which turns out to be not for every second thing even if it's unidiomatic, something about hammer and things looking like a nail).

In general, I think you either never worked with .NET at all or never understood it beyond surface level impression, and rely solely on urban myths about the topic of this discussion. Because there is no other way to explain the abstract "bottleneck" you imagine nor thinking as if Golang's runtime isn't a work-stealing scheduler just like .NET's threadpool, which it is.

> The only possible way to make this statement with confidence is never measuring the overhead of tasks and goroutines. Tasks are lighter than goroutines, especially memory-wise.

> In general, I think you either never worked with .NET at all

What a wild assumption to make, so I'll maybe counter it with the same claim for Go because what you write here isn't really true. It might be if you use standard goroutines which run with 8 KB stacks (even worse on Windows where you're paying an additional 4k because... well because Windows), but you both can and should modify this.

https://go.dev/src/runtime/stack.go

> Try spawning one million tasks and then one million goroutine.

I can run around 50 million goroutines on my macbook air. I can barely run 100k tasks. Task which again are asynchronous, which comes with a range of issues that you conveniently skipped talking about. I think that it is fine that you love C# and apparently hate Go, but maybe your personal opinion is getting in the way a little?

This is impossible. Baseline allocation size for an asynchronously yielding task starts at ~100B (because synchronously completing task may not allocate at all, some tasks are extended with additional pooling mechanic to not allocate in all scenarios through pooling or otherwise, like async socket operations).

What sample do you use for comparison? Maybe your gorotines do nothing but sleep and tasks do active work? I imagine Go would struggle even with just single allocation per goroutine if they do anything more if it is literally >= 50M goroutines. For example, BEAM already starts to struggle with 1M, at least spawning-wise, and Go runs out of memory easily at 10-30M if the only modification is GOMAXPROCS (which is what realistically everyone does).

Also hot splitting is very fun to fix by randomly rearranging the code.