I think it is very EASY to make a performance argument in 2020. In every domain, from my phone, to my desktop pc, to our huge AWS servers at work, I encounter software that is slow. We struggle with our C/C+ database at work running on top of a C/C++ operating system. We can't buy a bigger server and it isn't fast enough to handle the load we get recently recently due to covid. You think I should be happy to incur GC overhead in both the OS and Database? No way! That would cost us a lot of money, and require a more complex architecture. (which also costs money)
On my desktop and phone I encounter applications that are annoyingly slow to start up, to compile, all kinds of things. The last thing I want is JVM or .NET runtime overhead occuring even at the level of my operating system, device drivers, etc adding to that. CPU cache space is precious, the low level things that everything else runs upon should be as efficient as possible.
C++ fired back because integration was ugly (the SDKs are designed for C usage) and a lot of C developers that doesn't understand C++ well.
Go is used a bit, but again, training people for using it correctly is hard. And using the C SDK from Go is an obvious NO.
A lot there think that Rust would be in a similar situation that C++. Nice to have, but too much low level dependencies (hardware SDK) and high level (developers proficient in the language) to expect it to happen. Also, calling the SDK would convert everything I'm unsafe, so we are like in C, but with a language that nobody understands.
So, there are technical reasons, but also human resources and economic ones.
A complete Rust system would likely help solve most of these issues and drastically reduce these bugs, increasing development speed. Unfortunately the lack of native SDK in Rust is annoying, but some groups are making progress on STM and no-lib Rust. It’d be great if STM makers adopted their sdk and made an official one!
Currently since Rust doesn’t support my chip, I’m using Nim to generate C. It doesn’t solve all the data races noted above but having generics and easy data structures like tables and vectors is fantastic and I'm not second guessing the code all the time. A deterministic GC covers my memory usages fine.
Also, those high level languages require an OS. And many systems programs run on bare metal or a very minimal OS.
Edit: Also, the abstractions that higher level programming languages provide are often not really needed for low-level programming. In some ways, low-level programming is easier than application programming, since the actual programming required is often fairly straightforward and constrained by the application.
C# (per your example) is not orders-of-magnitude away from from C++ perf like Python is, but is w/in a very small constant factor, and often even faster for poorly-written C++ as GC is more efficient than calling copy c'tors where they needn't be called, for example.
And if you introduce features such as Span<> (and friends) and ref returns into your C# where you need them, you now how have safe GC-free/reduced code with perf that rivals Rust in the sections of code where you need it, with full GC as a backup.
One thing I like about Rust is the idiomatic way is usually very close to the fastest way. There are exceptions of course. But it you tend to get steered to efficient solutions.
With that said, there isn't much of an excuse for non-0-cost enumerators, etc. -- given that refactoring tools switch between foreach, linq, indexing or ptr/spanning, you'd think the compiler-chain or jitter could do the same. Roslyn is a better back-end for meta-programming, but it's too bad MS denies us the benefits of surfacing meta-programming to the language or at least tool level, or we'd have tools that could easily convert linq to highly optimized code.
You could also have compiler-enforced "levels" of C# code that had restricted features/semantics, such as "alloc-free", etc. - right now the choice is just "default" or "unsafe".
"LOH allocation detected for object 'MyNamespace.MyObject'. Attempted allocation bytes: 90K (maximum 85,000 bytes)."
Then one level up from that restriction would be the totally alloc-free approach you mention which could potentially mean the GC could be put into a special idle/framework-only mode. For alloc-free, I believe you could enforce this at compile time, as opposed to run-time for the LOH condition.
The performance overhead of a virtual vs non-virtual call on the CLR is negligible - same as with C++. For proof, look at Direct3D which is performance-critical, yet Direct3D’s API is based on COM which is all about vtable-calls.
Linq itself is also very decent. I won’t argue that Linq is perfect (e.g. suboptimal list allocations when the total output length can be known in-advance), but its hardly “slow” - certainly not enough to impact any production workloads - you’d only observe a difference between hand-written loops and a Linq expression in a contrived synthetic benchmark.
It isn’t. It looks like COM, but it isn’t.
Just asking because this article is quite clear about how DirectX is all about COM: https://docs.microsoft.com/en-us/windows/win32/prog-dx-with-...
> The Microsoft Component Object Model (COM) is an object-oriented programming model used by several technologies, including the bulk of the DirectX API surface. For that reason, you (as a DirectX developer) inevitably use COM when you program DirectX.
I am not sure about D3D9, but 10 and 11 and 12 are not COM.
Long-term: I feel that Swift was meant as Apple’s answer to C# and as way to retain XCode users as Objective-C became increasingly unfashionable over the past decade and Apple lost employees who could properly maintain it. Swift won’t go away, but I suspect that Apple doesn’t want to have to pay to maintain Swift while the rest of the industry gets to use it for free and port it to platforms that Apple won’t see any revenue from: i.e. Apple doesn’t want to be like Sun/Oracle and have other companies (Google) use their work (Java) for a competing platform (Android’s Dalvik).
So, I’m wary of adopting Swift - while Apple does currently support it on non-Darwin platforms right now I fully expect Apple to lose interest in maintaining first-class support for Windows and Linux at some point, just like how OpenStep was repurposed as a Mac-only when it became the rational decision for them.
Maintaining a thriving developer ecosystem and platform requires a degree of trust, transparency and a history of commitment to a product - and Apple (as a company) is the anathema of transparency.
However I think you are correct in that they won't want to put much effort into it. Their support for developers is already somewhat half-hearted if you compare it to Microsoft. Using XCode over the last few months has made me appreciate how good Visual Studio is. Apple's developer documentation has me missing Microsoft's.
[1] https://play.google.com/store/apps/developer?id=Apple+Inc.&h... [2] https://support.apple.com/en-gb/HT210384
It seems that it's not available both for the largest desktop platform, Windows, and for the largest non-desktop platform, Linux on ARM (https://swift.org/blog/swift-linux-port/ says "Currently x86_64 is the only supported architecture on Linux.") i.e. all the IoT devices which need code in a "systems language" and Android phones.
This is not a good approach in general. GC is only really needed in applications when working with data that's graph-like and potentially involves cycles of object references. A software project should be properly designed at the outset so that GC can be used in a "pluggable" way where it's strictly needed. Rust will probably enable this kind of use in the future, but other languages such as Go can already be used to comparable effect, seeing as they're generally limited to smaller pieces of code ("microservices") running in their own separate address space.
Fully agree with you that GC should be abstracted away and used for where it shines: cycles and graphs!
- Not leaking memory - Not invoking unsafe - Not angering the rust compiler
None of those efforts stabilized to my knowledge, and the libraries developed for this task all have experimental/research tags associated to them.
For better or worse all the guides for using rust strongly encourage avoidance of primitive cyclic structures such as doubly linked lists, graphs, and other structures in favor of statically allocated fixed size variants. Like golang's preference for map/list as the only primitive structures, this is a constraint that one can get used to for most problems. But it doesn't feel great that as a language there are basic algorithms and datastructures that can't be idiomatically coded in the language.
Still extremely new, of course, but has promise!
IMHO "systems" here means running on an OS, not network systems or internet apps.
So None, but you want to write libraries that are easily linked to all manners of 3rd party languages and can squeeze the last drop of OS performance. Your language with automatic garbage collection cannot do that. If all you end up doing is wrapping stuff with C or C++ headers then better use C or C++ at first place.
So I would say there is definitely at least one GC language that is worth using for systems level programming.
I agreed until this. I don't take anything not AOT compiled with an optimizing compiler as fast.
JITs may work well for numeric benchmarks with one tight loop, but there is extra memory and energy overhead.
Even parts of managed languages which are typically frowned upon from a "systems programming" perspective, such as GC, can be viewed as a positive when trying to iterate. GC can be treated like a backstop which helps to keep your application from exploding while you work on memory management, and then you can incrementally address heap alloc (aka latency) concerns with an application that actually runs (for a little while at least). Trying to iterate on memory pressure and related concerns with a C/C++ application is nothing short of nightmare fuel from my perspective, but I spend most of my time in higher-level languages these days.
I think it is also very hard to make a performance argument in 2020. Especially when you are comparing low level against something like the newest C#/.NET Core stack. Just take a look at the most recent TechEmpower plaintext benchmark (round 19). How many new business "systems" are being "programmed" that aren't ultimately just web servers passing HTML/JSON around, executing business logic, and reading/writing bits of data to some database?