11 ms·
Golang vs. C# (.NET 5.0) at Benchmarks Game
- Guillaume86 5y agoThe focus on performance since Core is really nice to see, dotnet 6 is continuing the trend as well: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-6/ https://devblogs.microsoft.com/dotnet/performance-improvemen...
- Thaxll 5y agoWhen you see how much effort it takes to C# and Java to optimize the runtime, there are a lot of people working on that. C# is fast but you see that it uses between 2 and 32 times the memory that Go needs. Overall you can see how fast Go is, it has little optimization compare to C# and it's as fast. Compare this: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/nbody-go-3.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... and overly complicated C# version: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/nbody-csharpcore-6.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... ( avx, Intrinsics etc ... )
- JamesSwift 5y agoI definitely have run into this, even when using 'server mode' in asp.net core. I never was able to figure out why the C# version of my POC was using so much memory, but rewriting to golang ended up using a very predictable, minimal amount of memory in comparison.
- azth 5y agoMy guess is that golang's GC is optimized for latency at the expense of throughput, limiting the max memory size.
- merb 5y agonah he just compares two different things. basically his golang hello world probably had basically nothing while his dotnet version used the "Microsoft.NET.Sdk.Web" which basically pulls the shared framework which will load a ton of stuff. BUT even after that the memory usage might be bigger. however does it really matter? I mean dotnet is not a big memory hog. it's pretty lightweight for what it is. compare it to java and the golang number would be insane.
- JamesSwift 5y agoI tried to do the most minimal, idiomatic design for both. I didn't save the C# code (I think it probably was just asp.net core and newtonsoft.json), but here is the go version [1]. It basically just loads a JSON file into memory then allows you to query the data with 2 API endpoints. [1] - https://github.com/J-Swift/GamesDbMirror-go https://github.com/J-Swift/GamesDbMirror-go
- merb 5y agowell asp.net core is not really minimal or idomatic. it pulls a whole framework your code doesn't do a lot of things that asp.net core would do. sadly since nancyfx died there arent that many c# http framework that are as lightweight as the golang once. asp.net core is more like java spring btw. nowdays most c# http frameworks do call `<FrameworkReference Include="Microsoft.AspNetCore.App" />` which is really really big compared to just Microsoft.NETCore.App most often the defaut aspnetcore also configures a "secure" application (working cors, etc.)
- xh-dude 5y agoIt is, and it’s not directly tunable … the opinion is ‘we’re IO-bound, not compute-bound’. I spent a chunk of time recently (10s of hours) doing dumb C# vs Go benchmarks - files and networking, and nothing worth taking seriously - just, usually the part about being IO-bound was true. C# is really impressive and was just a little slower with the best async solutions I could come up with. The machinery for async has overhead, so do Go routines and channels … the first-pass, not very performant code was just a little faster and IMHO clearer with Go (but I’m much better with Go /shrug).
- Mattish 5y agoServer mode is much less likely to incur GC. Were you causing enough memory usage to force your app to actually free memory? It will intentionally use more memory for the sake of throughput, hence why this post has all .NET program flag for it, as it's a _speed_ benchmark primarily.
- JamesSwift 5y agoI cant say for certain, but I'm pretty sure I manually GC'ed as a test and it didn't seem to help. Its been a while and the C# ended up being a temporary approach until I saw how much less memory the golang version used. They performed almost equivalently for RPS I believe.
- deleted 5y ago[deleted]
- agumonkey 5y agoand afaik, .net has record types unlike the jvm (yet) which means java is even worse
- kaba0 5y agoI think you mean structs (value types. Will be called primitive types in Java). Records are not too interesting from a performance pov (and java has them, and I think they actually predate c#’s), though java will likely be able to optimize serialization/deserialization of records better.
- ternaryoperator 5y agoJava recently added record types.
- igouy 5y agoCompare this and C# version: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/nbody-csharpcore-3.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
- joelfolksy 5y ago"( avx, Intrinsics, etc ... )" I have to give you credit for trying to apply the Rule of Three to a single criticism. Of course, I don't really understand how the fact that someone took the time to vectorize the C# submission is supposed to be a mark against C#...
- melling 5y agoI was always under the impression that Go never had a great optimizing compiler. It was never a primary focus given the limited developer resources. I couldn’t find a direct C# to Rust comparison but Rust trying to compete with C++ means performance is a goal, if that’s what you are after. https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-go.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
- throwaway894345 5y agoI don't think it was "limited developer resources" so much as a desire to preserve blazing-fast compile times. The very rough rule-of-thumb that I've heard is that optimizations must pay for themselves (a compiler which is itself compiled with the given optimization must not be slower than the previous version).
- igouy 5y ago"He used the compiler's self-compilation speed as a measure of the compiler's quality. Considering that Wirth's compilers were written in the languages they compiled, and that compilers are substantial and non-trivial pieces of software in their own right, this introduced a highly practical benchmarks that directly contested a compiler's complexity against its performance." p44 "Oberon — The Overlooked Jewel" Michael Franz, in "The School of Niklaus Wirth". https://www.google.com/books/edition/The_School_of_Niklaus_Wirth/6kHs4s-79bkC?hl=en&gbpv=1&bsq=self-compilation%20speed https://www.google.com/books/edition/The_School_of_Niklaus_W...
- the_duke 5y agoThere are both GCC [1] and LLVM [2] backends for Go, but I don't think they see much usage compared to the default. [1] https://golang.org/doc/install/gccgo https://golang.org/doc/install/gccgo [2] https://go.googlesource.com/gollvm/ https://go.googlesource.com/gollvm/
- gwp 5y ago> I was always under the impression that Go never had a great optimizing compiler. It was never a primary focus given the limited developer resources. It's an intentional choice, that's why it compiles code so fast. Also because of that it's a lot simpler than say GCC. Before Go, the Plan 9 C compiler was designed in a similar manner too (I think the Go compiler was forked from it). I think the simplicity aspect is even more important than the compiling speed. It's easier and cleaner to keep the compiler simple and write optimized assembly code by hand when it's needed. That way, the compiler doesn't get so messy (fewer bugs, easier to maintain...) and the written program is of better quality (humans can produce better code than compilers).
- flyinglizard 5y agoI say modern .NET is a marvel of features, development tools, interoperability, performance and even ships with its own cloud environment (Azure). Unfortunately developers who don’t know better judge it by it’s historical association with Windows rather than how powerful it is today.
- umvi 5y agoCan you now get the full .NET development experience in a Linux-only environment? I haven't used it in a while, but from using Unity (game engine) it seemed like C# on Linux was a bit crippled
- deleted 5y ago[deleted]
- moonchrome 5y agoYes, use Rider and .net core - everything works on non-windows platforms (working on .net from osx right now, deploying to linux) Avoid vscode for C# development, unlike TS/JS (which is top of the line), the support for C# even in core is toy level.
- lostmsu 5y agoWhat do you think is lacking in C# extension for VS Code vs TypeScript? I would expect a better experience with C# (in terms of tooling) because the language is typed.
- moonchrome 5y agoIt just doesn't work nearly as well - even on simple .NET core solutions created from CLI intellisense chokes up, refactoring doesn't work, it's nowhere near the quality level of TS.
- foepys 5y agoEven TS support is pretty lackluster compared to Rider's and VS' C# support.
- popotamonga 5y agoIs there one similar for c# vs scala?
- igouy 5y agoMany years ago — but from version-to-version too many of the Scala programs suffered bad bitrot, failed and were not updated.
- kaba0 5y agoScala code is backwards compatible, only the class files are not - so at most dependencies could have become stale. With a recompile, the programs should work just fine.
- igouy 5y agoRequirements changed; and neither the original program contributors or anyone else on the scala mailing list wished to update the programs. (The scala mailing list archive doesn't seem to go back that far.)
- throwaway894345 5y agoI can't imagine a better setup for a language flame war :). I really like debating languages, so I hope it doesn't go that direction. One of the standard caveats with this particular benchmark game with respect to Go is idiomatic optimizations are prohibited. To use the btree example, Go's memory management is low latency and non-moving, so allocations are expensive--any Go programmer writing a performance-sensitive btree implementation would pre-allocate the nodes in a single allocation--an absolutely idiomatic and trivial optimization--but the benchmark game requires that the nodes are allocated one at a time. In other words, the C# version is idiomatic, but the Go version is expressly contrived to be slower--not a very useful comparison. Mad respect for .Net though; it's really impressive, I like the direction it's going, I'm glad it exists, etc.
- abledon 5y agoreminds me of the 'im tired of being a hipster' post on frontpage recently.... "go learn 'unhip' tech/languages and live your life"
- na85 5y agoThis one? https://news.ycombinator.com/item?id=28274485 https://news.ycombinator.com/item?id=28274485
- igouy 5y ago> absolutely idiomatic and trivial optimization Which is not accepted for the C# programs either. sync.Pool is accepted — https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/binarytrees-go-6.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... > the Go version is expressly contrived to be slower The requirements were contrived in April 2008. afaict Go initial release was March 2012.
- throwaway894345 5y ago> Which is not accepted for the C# programs either. Because C# doesn't benefit from this kind of optimization. Its GC is generational, which means that it has very fast allocations at the expense of high latency. In most applications, lower latency is more important than slower allocations (not least of all because these batch-allocating optimizations are nearly trivial), but these benchmarks don't reflect that at all. > The requirements were contrived in April 2008. afaict Go initial release was March 2012. Contrived = "the rules artificially prohibit idiomatic optimizations". It doesn't require that the maintainers have a prejudice against Go (although as you point out, the maintainers have had a decade to revisit their rules).
- scanr 5y agoI enjoy using both languages. The significant performance difference between the two for me is compilation speed. Size of binaries produced is also important if you’re shipping them around.
- nedsma 5y agoIt's 2021 and .NET developers still argue which coding style they should adopt and how they should enforce it. It's totally mind numbing that team members are split between implicit and explicit variable naming. Contrary, in Go you just write code because those nuances should not matter.
- Salgat 5y agoThat's more of a failure of management. Companies like Google outline style guides for company-wide usage. It might not be "the best" but it's consistent and the company enforces that.
- codenesium 5y agoThat nuance does matter which is why we are still having the discussion. Teams can pick which style they want but mixing is unnecessary overhead and when you're talking about 10s or 100s of solutions I'd like the style to match across the board.
- booleandilemma 5y agoI'm not really concerned with such small differences in speed, to be honest. The thing that I look for is: how productive am I when using language X?
- Koshkin 5y ago... and nothing can compare with C# (under Visual Studio) in this regard, it seems. Not the most efficient at run time, but a good, knowledgeable developer's productivity is insane.
- Salgat 5y agoEspecially with the .NET Standard Library. It has damn near everything already out of the box with 1st class support, and if not there's almost certainly a nuget for it. C# is an extremely productive language to develop for.
- keewee7 5y agoI prefer C#. But here the Go code actually looks like normal production code while the C# examples look like something made by a low-level optimization wizard.
- alkonaut 5y agoI looked at the k-nucleotide, n-body, etc and saw nothing out of the ordinary in terms of C#. There wasn’t even a lot of “modern C#” low level optimization like ref-structs/spans and similar. It actually looks like there is quite a bit of performance from C#8, 9, 10 left on the table.
- coder543 5y agoAre we looking at the same file?[0] Tons of very "interesting" attributes like this: // prevent inlining into main to decrease JIT time to generate main [SkipLocalsInit][MethodImpl(NoInlining)] [SkipLocalsInit][StructLayout(LayoutKind.Explicit, Pack = 32)] [SkipLocalsInit][MethodImpl(AggressiveOptimization | NoInlining)] [FieldOffset(32)] and tons of "unchecked" blocks. Not to mention that the entire file is using explicit vectorization, which I consider to be a very high degree of optimization -- tons of software never bothers to implement explicit vectorization, and does just fine. If all of this is "nothing out of the ordinary", then "ordinary" C# has changed a lot since I last spent much time with it. [0]: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/nbody-csharpcore-7.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
- alkonaut 5y agoAgree - those attributes are definitely “low level” and not idiomatic in most situations. I must have missed them skimming that file. For the particular case of n-body you could argue you are already in a pretty extreme HPC world and doing it without vectors would basically be a toy calculator. The problem then of course that C# isn’t really ever idiomatic for that. The question (as alaways) becomes about what to compare. Typical or pushed to the limit.
- fulafel 5y agoPlease fix the title (the original title spells Go correctly too).
- matttproud 5y agoI've never understood why folks treat the Benchmarks Game results as indicative nor representative of anything useful. The code specimens they use are often unpolished nor idiomatic, without even commenting on whether they could be made to perform better through Byzantine, careful by-hand optimization. Why does their web site have no contact nor link to where the source code for the project can be checked out, contributed to, or amended?
- igouy 5y ago> I've never understood why… Perhaps they don't read the website text? > … no contact nor link… Search works.
- matttproud 5y agoI ran multiple search queries. I wouldn't be so dumb to post a comment like this here without having done my homework. The best I found after trying numerous keyword permutations was https://salsa.debian.org/benchmarksgame-team/benchmarksgame https://salsa.debian.org/benchmarksgame-team/benchmarksgame, but this did not appear to contain all of the benchmarks' source, just the source embedded in HTML, which is specious at best. This repository looks mostly like frontend HTML and chrome, not a SUT, executor, nor even the sub-test code. At the very least, I couldn't realistically re-run some of the example benchmarks from the source embedded in the HTML, because they did not include vendoring/version information for external packages they depend on. That made me doubt the provenance of https://salsa.debian.org/benchmarksgame-team/benchmarksgame https://salsa.debian.org/benchmarksgame-team/benchmarksgame.
- igouy 5y ago> … just the source embedded in HTML… "Where can I get the program source code? — zip'd program source code" line 11 ? in the README > … vendoring/version information for external packages they depend on… If the programs don't build/run with the latest GA external packages, they will be shown as "Make Error" "Bad Output" "Failed" until someone updates them.