Hacker News new | past | comments | ask | show | jobs | submit login

How well does C# work for this cross-platform? Are its executables very large?

I considered using Go for command-line apps - but in my case they often have to interact with existing C++ code. That’s easy enough to do from Python, but I was advised that interop with other languages is an area in which Go is particularly weak.




I think a standalone "Hello World", built with .NET Core, is around 60-70 MB large on both Linux and Windows. The startup times are alright - slower on Windows than on Linux in my experience because of the file system performance.


Lower than this. If I use the AOT compile option with .NET Core 3.1 I get a 40MB binary which goes down to 10MB with the trim option.

Just like Go which embed it’s runtime, .NET Core binary compiled with AOT embed the CLR but, unlike Go, it has options to trim out the pieces that aren’t necessary, which I really like.


I did not know about PublishTrimmed and will try it out. Thank you.


I think this is one of those features that was a bit preview in 5 and you should use the just-released v6 for PublishTrimmed. There are also situations where it doesn't work out of the box (e.g. Winui3!)


> I think a standalone "Hello World", built with .NET Core, is around 60-70 MB large on both Linux and Windows.

Lol what?

What goes into a 70 MB implementation of 'hello world'?


It’s not a 70 MB implementation of Hello world. It’s a 70 MB compressed runtime with a standard library (or at least the most basic parts of it) and a couple KB "Hello world".


Why is the runtime so huge and why is so much of the standard library included?

Java ‘hello world’ compiled into a static binary is just a couple of MB.


The runtime is huge because it includes a very large standard library. Using the .NET linker you can create a "trimmed" binary that only includes the code that actually gets used. A Hello World compiled this way takes 14MiB "Ready to Run" with native code included, or 11MiB without.

For a modern CLI app it's basically that easy. For an older or GUI WPF app it's not. It used to be fashionable in .NET to use lots of runtime reflection, dynamic runtime configuration based on config files, dynamic loading, and runtime code generation. I suppose the language was less featureful back then and people looked longingly at Enterprise Java for some reason. This type of dynamism doesn't work with AOT compilation because the compiler needs to be able to statically determine what code is required. The solution is to remove the dynamism, replace it with compile-time code generation, or annotate the reflection to tell the compiler which types will actually be used. As of .NET 6 most of the standard library has been annotated or otherwise made compatible with trimming[0]. WPF apps will probably never be able to use trimming because that's a huge amount of code and MS has like one intern working on it.

I believe the situation with Java is basically the same? You can't just build a Java 6 Spring app into a small AOT bundle, right?

[0]: https://themesof.net/roadmap?product=.NET&release=6.0&q=trim


See PublishTrimmed: by default it includes all the standard library. "Trimming" is what almost all C-style linkers do by default, but C# doesn't because there are some reflection issues (e.g. you can reference types by strings and construct them at runtime, which would fail in a Trimmed environment unless you explicitly tell it not to trim those types).


Can this couple MB static binary run without JRE?


Well it wouldn't be very 'static' if it couldn't, so yes of course.


Could you point me to where I can learn how to do it?


If you use legacy .NET (which is preinstalled on Windows) a GUI Hello World is about 10 kB.


gRPC is one way to go about it if you have control over both c++ and go. Go binaries work pretty consistently across Linux which is a positive.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: