Coder Social home page Coder Social logo

Comments (10)

AliveDevil avatar AliveDevil commented on May 2, 2024

Not quite sure when I can take a moment to implement this, but trimming reduces the self-contained single file publish from 90 MiB to 20 MiB.

from stl.fusion.

alexyakunin avatar alexyakunin commented on May 2, 2024

Hi, yes, there was no IL trimming markup.

I've just added one: 12e586d

The downside is: prob. it still won't work, coz interceptor types aren't referenced. One solution would be to generate module initializers to "hold" them.

For now you can manually reference these types - try TypeExt.MarkUsed<T>(), I added it for this purpose.

from stl.fusion.

alexyakunin avatar alexyakunin commented on May 2, 2024

Honestly, I don't understand why they even came up with NativeAOT:

  • Static analysis isn't good enough to resolve even simple things - e.g. you pass ICommand<T> & want to construct CommandContext<T>. How can you do this, assuming you pass TCommand or ICommand (base type)?
  • Stl.Rpc & Fusion use way more complex transforms in some cases - e.g. RpcInboundCall<TResult> is used for any incoming call with result type TResult; ArgumentList<TArg1, TArg2, CancellationToken> is transformed to ArgumentList<TArg1, TArg2>, etc. - all these decisions are made relying on Reflection.
  • IL Emit is used in a decent number of scenarios as well - e.g. to generate fast getters for properties which aren't known at compile time.
  • Things like DbEntityResolver use expression trees to build pretty advanced queries.
  • Etc.

In other words, I don't see how purely static AOT is even usable anywhere but in some toy projects.

What they should really focus on is profile-guided AOT - AOT is almost solely about startup time, and all you need is to know what runs on startup. And it's easy - just run & record it. And it's 100% fine if you compile just this & interpret or JIT-compile the rest - in fact, they do exactly this on MAUI Android.

One other thing with NativeAOT is: you may try to play with it if you start something new. But imagine a huge app that's already there - what kind of mindset you are supposed to have to decide to try it, if it's a huge investment, and "all or nothing" in the end, but most likely "nothing"? Just look at these 2.5K of code in above commit - what I was doing is ~ "ok, let's do the best we can & see what stuff I can't resolve statically". And I can name like 10+ pretty complex scenarios I simply couldn't cover (some are listed above). And that's for a single library.

Long story short... IDK who came up with NativeAOT idea, but this guy definitely doesn't know how real-world apps look like.

from stl.fusion.

alexyakunin avatar alexyakunin commented on May 2, 2024

I kinda angry about this b/c they invest so much into this crap vs focusing on what really matters - i.e. profile-based AOT. All this shit with [DynamicallyAccessedMembers] no one really wants to see - why, why to even pollute the code with all of that stuff, if it doesn't really work?

And it's the same about trimming. Just decide what you want to keep in AOT vs MSIL form based on stored startup profile, that's it!

from stl.fusion.

alexyakunin avatar alexyakunin commented on May 2, 2024

And it would be way more useful if, instead of focusing on what to trim, they'd focus on how to split the code into 3 "pieces":

  • Absolutely necessary (comes as AOT/native code, loaded before app startup)
  • Reachable in 2-3 hops (comes as MSIL, loaded before app startup)
  • Maybe necessary (comes as MSIL, loaded in the background after your app starts).

from stl.fusion.

AliveDevil avatar AliveDevil commented on May 2, 2024

Think I've struck a nerve here 😅

For now you can manually reference these types - try TypeExt.MarkUsed<T>(), I added it for this purpose.

Nice, will check it.

And it would be way more useful if, instead of focusing on what to trim, they'd focus on how to split the code into 3 "pieces":

That's been tried with ReadyToRun, and requires double the application size for both the managed and AOT compiled bits - which imo wasn't viable from the beginning.

why, why to even pollute the code with all of that stuff, if it doesn't really work?

Checked the commit, and I do agree: That's just a burden.

I'm not that involved in the wider .NET core world, as I'm still dependent on .NET framework … I might be influenced by shiny new things for my personal/hobby projects though - and may very well run that specific app with --self-contained -p:PublishSingleFile=True without ever enabling NativeAot or trimming (the target environment this app should run on isn't constrained in any way).

Just to confirm for future enhancements: All-of Stl should be trimming-friendly, not just parts of it.

I'm fine with a non-solution closure, just to keep this topic in here for future reference.

from stl.fusion.

alexyakunin avatar alexyakunin commented on May 2, 2024

Nice, will check it.

[DynamicDependency(...All, type(...))] actually does the same, I removed the method :)

from stl.fusion.

alexyakunin avatar alexyakunin commented on May 2, 2024

Just to confirm for future enhancements: All-of Stl should be trimming-friendly, not just parts of it.

Speaking of which, I just added [DynamicDependency] to every builder indicating what should be kept. So now you should prob. just reference proxy types with [DynamicDependency] from somewhere, later I'll start generating a module initializer for these types to make sure they're kept no matter what.

from stl.fusion.

alexyakunin avatar alexyakunin commented on May 2, 2024

As for NativeAOT, the main issue is that Reflection and IL emit is broken there. So all they need is to add an interpreter to handle this - it's kinda fine in most of scenarios, even if it's slower.

from stl.fusion.

AliveDevil avatar AliveDevil commented on May 2, 2024

I see. So the generated proxy still gets trimmed, but the factory interceptor is kept in the trimmed build.

Module initializer is definitely the easiest solution here.

from stl.fusion.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.