10 ms·
I just really wish they start investing into true static compilation for .NET. Some serious projects [1] started adopting CoreRT [2], despite Microsoft's negle
by netacean 6y ago
I just really wish they start investing into true static compilation for .NET.
Some serious projects [1] started adopting CoreRT [2], despite Microsoft's neglect for their own runtime. CoreRT seems to really deliver on the single-file fast-startup small-size .NET promise. Getting this project folded into the LTS .NET 6 release should be a priority.
The source generators [3] that are coming to .NET 5 easily cover 99% of our Reflection.Emit use cases, so the JIT is going to be more of a legacy burden once .NET 5 comes out.
I want Go's small size, fast compile times, fast startup, without Go's bs (explicit error checking, seriously?).
Pieces of our software get deployed over a satellite link so yeah, megabytes matter (and that's why I don't even dare to propose using .NET for those parts). Sharing code with the rest of our .NET stack is a PITA though so people are getting itchy to rewrite the rest of our .NET stuff in Go for better sharing (the Reflection.Emit parts would be replaced with "go generate" which is... a source generator). It would be good to get some clarity on the static compilation roadmap in .NET because I like my job, but I also don't want to become a fulltime Go developer.
[1] https://github.com/dotnet/corert/issues/7200#issuecomment-624618015 https://github.com/dotnet/corert/issues/7200#issuecomment-62...
[2] https://github.com/dotnet/corert https://github.com/dotnet/corert
[3] https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/ https://devblogs.microsoft.com/dotnet/introducing-c-source-g...
- jeswin 6y agoCoreRT is definitely the most exciting project in the .Net stable. But there seems to be some people within MS who don't want to go in that direction - mostly for the reason that it won't be compatible with all of the existing code out there. I just wish they'll see that most users would gladly trade some compatibility for smaller size and faster execution.
- cm2187 6y agoBut you can’t go very far without serialization libraries these days. Would CoreRT be able to deal with that?
- Kipters 6y agoIf it works anything like Mono AOT (used in Xamarin.iOS and Xamarin.Android) you can probably annotate parts of your code to be preserved. A couple of days ago I found this though, it works using source generators and so it doesn't require reflection to work: https://github.com/TomaszRewak/C-sharp-stack-only-json-parser https://github.com/TomaszRewak/C-sharp-stack-only-json-parse...
- thomasz 6y agoThe new compile time code generation feature should largely eliminate the need for using runtime reflection, at least for serialization.
- Const-me 6y ago> so the JIT is going to be more of a legacy burden I use Reflection, Reflection.Emit, and Linq.Expressions not just for serialization. Building code in runtime from something else can be a win, especially performance but sometimes development time as well. That "something else" is not necessarily other code: https://github.com/Const-me/Vrmac/blob/master/Vrmac/Draw/Text/Kompiler.cs#L9-L15 https://github.com/Const-me/Vrmac/blob/master/Vrmac/Draw/Tex...
- naasking 6y agoYou can replace code generation used for serialization with open delegates, and that should work without any special runtime magic: https://github.com/naasking/HigherLogics.Google.Datastore/blob/master/HigherLogics.Google.Datastore/PropertyMapper.cs https://github.com/naasking/HigherLogics.Google.Datastore/bl... Constructors are the only odd duck for which there is no efficient alternative. You either generate a delegate at runtime to call the right constructor, or you have to use reflection/Activate.CreateInstance.
- alkonaut 6y agoWhat's the reason you can't use AoT compilation together with serialization? The only thing that's problematic is reflection, but I wouldn't use reflection in my serialization if I can help it.
- zvrba 6y ago> Pieces of our software get deployed over a satellite link so yeah, megabytes matter (and that's why I don't even dare to propose using .NET for those parts). Megabytes are a one-time thing, unless your app is HUGE. Once you've deployed the runtime and dependencies, you can only redeploy your application DLLs.
- netacean 6y ago> Once you've deployed the runtime and dependencies, you can only redeploy your application DLLs. We looked into that but we can't run with an unpatched runtime. And servicing the runtime involves installing a huge package several times a year.
- apta 6y agoWhat kind of software are you developing that gets deployed over satellite links? Sounds interesting.
- netacean 6y agoDon't want to go into much detail here but it involves ocean vessels.
- throwaway8941 6y agoI apologize if what I'm saying sounds obvious, but have you tried not sending whole binaries/archives, something like delta RPMs / pdiffs?
- randombytes6869 6y agoI remember reading about this in Java world a while back. To maintain safety you need to validate all the bytecode on load, so you can't really pre-cache it. Newer versions of Java use "class data sharing", but this only caches code after the local JVM has already validated it. Doesn't help with code files you've never seen before. You could abandon validation and pre-compile but then running applications is no safer than c. You could modify the IR to do bad things like leak memory and crash VM. JS has the same problem. Parsing and validating JS is a large part of page load times these days. I'm not sure source generators will be the solution you hope for. Java has supported build time code generation for ages but everybody still reaches for reflection. A few popular libraries like MapStruct use build time generation instead of reflection, but again there's like 20 other popular libraries that do the same thing with reflection. Java has attempted to fix the reflection hole with modules. You're supposed to pre-declare the classes you're reflecting in your assembly. But at current adoption rates its going to be another 20 years before you can count on all your dependencies using the module system correctly. Trimming unused code is easy without reflection. Its been standard practice on Android for a long time. But every time I've tried to use it on servers I run into random crashes cause by runtime reflection and classloading. Pretty unfortunate shortcomings to Java and C#. I don't think they'll ever be truly fixed unless somebody uses to nuclear option of disabling reflection completely
- CuriousSkeptic 6y agoDisabling runtime reflections is key. Most of what it’s used for can be done compile time anyways. But more importantly reflection enables circumventing the type system and doing all sorts of unsound things. As long as you have a compile time option I don’t thinks it’s nuclear, it just makes sense.
- kasperni 6y agoFor Java's case the benefits of build time code generation are greatly exaggerated. In many cases, it is a lot faster and easier to generate code at runtime using MethodHandles then build-time code generation. For example, the toString/hashCode/equals methods of record types (that are being added with Java 14). Are all generated at runtime via indy (Invoke Dynamic) instead of generating the bytecode for them at compile-time.
- chadcmulligan 6y agoHave you looked at Delphi? Single executable, small size, multi platform if you want it, etc
- boomlinde 6y agoAnd a license that's going to run you at 1700€ the first year and 440€ on renewal. It's spare change for a successful company but I have to wonder if it doesn't hamper adoption, especially when there's a seemingly obvious free and open source alternative like Lazarus + Free Pascal
- chadcmulligan 6y agoTheres a free version of Delphi to https://www.embarcadero.com/products/delphi/starter/free-download https://www.embarcadero.com/products/delphi/starter/free-dow...
- jksmith 6y agoI'm writing a pretty serious app in FreePascal/Lazarus right now that's working out nicely. At some point, the Delphi cost may be justified, but not right now. Plus, the code injection macros in FPC (Delphi doesn't have) are addictive. I haven't tried on MacOS yet, but the transparent compile ability across Windows/Linux for desktop UI is pretty amazing.
- chadcmulligan 6y agoShould probably look at them again - they were painful to get running last time I looked. Edit: It seems the cross platform is still difficult? particularly iOS, at least compared to using Delphi for iOS
- cchance 6y agoHave you looked at rust?
- 6y ago
- legulere 6y agoC# code still uses too much reflection (serialization, asp net routing, ORM, view model binding) to be statically compileable. They seem to be doing something against that with code generators
- voxic11 6y agoReflection isn't an issue. CoreRT allows you to include the symbols for reflecting on though it does increase the filesize significantly.
- vips7L 6y agoThe trouble comes in your dependencies when you don't know what they're reflecting upon or what features they're using that aren't supported.
- randombytes6869 6y agoThis is exactly what newer versions of Java allow you to do. The problem is, nobody does it. I really like C# as a language, its better than Java in nearly every way. But this is a rare case where C# is implementing a feature Java has had for a very long time. And just like in Java, I don't think it will have the impact advertised.
- Ididntdothis 6y agoThe funny thing is that a lot of reflection is made necessary because of the lack of a preprocessor. Considering that everything old comes back after a few decades as a new innovation with a shiny new name I wouldn't be surprised if the preprocessor came back to support static compilation.
- randombytes6869 6y agoC# and Java are both guilty of this. I don't think generators will help nearly as much as hoped, because Java has the same problem even though it supports build time code generation through Annotation Processors for like over a decade, since Java 7 I think. Reflection is just easier. Unless you go out of your way to use libraries that use code generation, Java is just as bad as C# in this regard. There's a few bright spots, like MapStruct for object->object mappings and Dagger2 for dependency injection that are built entirely on code generation. But these are exceptions to the norm
- mycall 6y agoI could see .NET supporting Rust before it supports Go given the recent announcements with Project Reunion.
- pjmlp 6y ago.NET Native?