3 ms·
Multi-core scaling (in particular within GC) is one of the strongest points of .NET (for example, Go used to have poor scaling on many-core systems (has this ch
by neonsunset 3y ago
Multi-core scaling (in particular within GC) is one of the strongest points of .NET (for example, Go used to have poor scaling on many-core systems (has this changed in 2024?) while in .NET the throughput would continue scaling linearly)).
- pdimitar 3y agoI really doubt that this is true, might be your bubble. Have you dabbled in Erlang/Elixir? Your standards would increase substantially if you did.
- neonsunset 3y agoWouldn't that be trying out something that is a strict downgrade? (bytecode interpreter based VM with weak JIT, GC is likely much weaker too) It really comes down to performing as much work on a core-local basis and .NET SRV GC does already a lot to avoid inter-core synchronization cost (per-core heaps, I'd expect JVM GCs do a similar, maybe better, job), and so does various thread-safe code in the standard library.
- pdimitar 3y agoTo answer your question: To see how far behind everything is in terms of parallelism and concurrency. It's not even funny how primitive 99.9% of everything out there is in this area.
- neonsunset 3y agoMaybe compared to C++ or even Go (yes, Go is very rudimentary with examples expecting you to synchronize goroutines by hand), but unlikely compared to C#. While both parallelism and concurrency are not as central to it as to Erlang, it is a much more approachable language and achieving either or both is trivial: // Concurrency using var http = new HttpClient(); var req1 = http.GetStringAsync("https://example.org/"); var req2 = http.GetStringAsync("https://news.ycombinator.com/"); Console.WriteLine(string.Join('\n', await req1, await req2)); // Parallelism var user = Environment.GetFolderPath( Environment.SpecialFolder.UserProfile); var hashes = Directory .EnumerateFiles(Path.Combine(user, "Downloads")) .AsParallel() .Select(path => { using var file = File.OpenRead(path); return Convert.ToHexString(SHA256.HashData(file)); }) .ToArray(); Console.WriteLine(string.Join('\n', hashes)); For distributed computing, there are Orleans and Akka.net frameworks which allow to achieve it at scale and garden variety of other, simpler frameworks for job scheduling.
- pdimitar 3y agoOK, but syntax by itself is not saying much. Ruby's ractors can look similar but the underlying implementation is subpar. Does C# have actual green threads or actors? Proper work-stealing schedulers, low-latency guarantees etc.? If so, that would be cool, Erlang's BEAM VM desperately needs competition. But I doubt it. From what I am seeing regularly on HN, people prefer to degrade or belittle / minimize the value of the BEAM VM than to admit that the runtime of their favorite language is still not good enough. Cognitive dissonance is getting in the way it seems. Shame.
- neonsunset 3y ago"Does this have Green threads?" is a common fallacy (along with mentioning function coloring) and arguably much worse API than Task/Future-based concurrency primitives because it does not give idiomatic control over yielding/dispatching and hides an important characteristic of the executed code, specifically, calls being a promise to produce a result in the future (e.g. the example above with http requests is much clunkier without them). Some languages intentionally opt for a much more limited way of doing it like Go with goroutines and channels, some have to retrofit an async-alternative to benefit the existing decades of code like Java, and some languages eventually got it right like F#, C#, in a way, Python and JS/TS, and, to dismay of many (and pain I sympathize with), Rust. Also, in C#, the way to go about it is to just pick the abstraction you think fits the problem best, be it manual threading, async/await Tasks (or anything custom that integrates with it), channels or, as you mentioned, actors for which there are Akka.NET and Orleans. I believe F# is even more flexible in this area. As for the implementation details of BEAM VM - just look at e.g. the times in 1BRC challenge for BEAM-based submissions - the rift between compiled languages and the former is immense and likely unclose-able, and this trend persists in any (micro)benchmark for BEAM I look at - the overhead of most trivial operations is just too damn high! It was a groundbreaking technology at its inception but today - likely not anymore. Not sure what* makes you quick to assume that the people working on .NET, JVM and other platforms which care about performance in (massively) parallel domains don't know what they are doing but work-stealing schedulers are yesteryesterday news and "everyone" does them (.NET, Tokio, Go from what I know), both in the form of threadpool implementations and in the form of bespoke parallel abstractions (both examples in my previous comment have these). Same applies to latency-minimization techniques, priority scheduling (worst case you can always have a dedicated worker thread that runs at higher prio, or a scheduler with a pool of those) and more. (* If you have been burned by Ruby - I did hear about it being subpar in all kinds of ways and observed being very slow but that should rather be an exception than the rule among other languages)