Let's talk performance

135678

Posts

  • BradChase.2654BradChase.2654 USMember ✭✭✭

    @DirkWilhelm Yes that is what we currently do. Matter of fact we HAD to because of the size of the apk.

  • stevefoxover.5931stevefoxover.5931 USMember ✭✭

    Sorry to say that I am looking into React Native instead. I spend more time looking for workarounds than actual coding. C# is my preferred language but Xamarin forms needs about 2 years of solid work. The forms previewer always fails with unknown error. So I have to dev and rerun to see UI changes. React Native is just click RR on the keyboard to see UI changes. Also the documentation is bad in Xamarin forms. Its old and incomplete. Microsoft needs to really hire and staff it to make Xamarin production ready.

  • AbdullahNAAbdullahNA INMember ✭✭

    It looks like the EntityFrameworkCore takes ~4 seconds to execute its "Migrate()" method consistently in every startups on Android. So as we would expect this adds up to the Xamarin.Forms initialization timing resulting up to ~8-10 seconds at the startup. This is way too much to have from a user's stand point. Inserting the db init code in the Splash Activity on a different thread (like below) believing Xamarin.Forms init and the db init would run in parallel, doesn't seem to be making any difference. Any help/suggestion would be much appreciated!

        protected override void OnResume()
        {
            base.OnResume();
    
            System.Threading.Tasks.Task.Run(() =>
            {
                App.DbFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                App.InitializeDb();
            });
    
            StartActivity(typeof(MainActivity));
    
        }
    
  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    Thanks, @EZHart . So at least it does not get worse with this change.

    What I'd really like is that my users don't have to use two different controls (Button and AppCompatButton) depending on if they use AppCompat or not. I'll open a thread in the Evolution Forum for that.

  • AbdullahNAAbdullahNA INMember ✭✭

    @DavidOrtinau I was just wondering if you have any comment/suggestion on my recent post above? (Posted on 20th April 7:19AM).

  • EZHartEZHart USXamarin Team Xamurai

    @AbdullahNA - Is it taking 4 seconds when there are actual migrations to apply? Or does it take 4 seconds even when there's nothing for it to do?

  • AllDayerAllDayer AUMember ✭✭

    @DavidOrtinau said:

    @nadjib said:
    Startup time is far from optimal especially on Android. 5 to 10 seconds to launch an app, means we'll loose customers. It's as simple as that. You should bring it to < 3 seconds.

    Yes, we continue to look for opportunities to improve startup. What's your minimum Android API version?

    What impact does the minimum Android API have on performance?

  • AbdullahNAAbdullahNA INMember ✭✭
    edited April 2017

    @EZHart No matter, if there is a migration to apply or the db is upto date. It consistently takes ~4 seconds in every startup.
    Also, just was wondering, why the parallel run with a different thread contributes to the startup time?

  • EZHartEZHart USXamarin Team Xamurai

    @AllDayer said:
    What impact does the minimum Android API have on performance?

    Forms currently supports API 15 and up. In order to do that, it has to do a fair amount of things like "if we are currently running API 21 or higher, do X, otherwise do Y". One of the options we've been looking at is whether we can improve performance by changing how we support different API levels, which is why that's a question we're asking people.

  • EZHartEZHart USXamarin Team Xamurai

    @AbdullahNA said:
    @EZHart No matter, if there is a migration to apply or the db is upto date. It consistently takes ~4 seconds in every startup.
    Also, just was wondering, why the parallel run with a different thread contributes to the startup time?

    Do you typically have DB updates to apply? If not, I think it's possible to turn off the migration step.

    As for why running in another thread doesn't help, without seeing the source code it's hard to say.

    Possible reasons I can think of:

    1. Something in your MainActivity is making use of the data access layer, and is blocking until the database initialization is complete

    2. Something in MainActivity is using a resource that the database initializer also needs (e.g., maybe both of them are reading/writing local storage heavily)

    But that's just speculation.

  • DH80DH80 USMember ✭✭
    edited April 2017

    @EZHart on android I see this on startup taking the longest. I am using the timing debug log

    Runtime.register: type=Xamarin.Forms.Platform.Android.PlatformRenderer, Xamarin.Forms.Platform.Android, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null

    What is this doing?

  • EZHartEZHart USXamarin Team Xamurai

    @DH80 said:
    @EZHart on android I see this on startup taking the longest. I am using the timing debug log

    Runtime.register: type=Xamarin.Forms.Platform.Android.PlatformRenderer, Xamarin.Forms.Platform.Android, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null

    What is this doing?

    That's the main renderer for the platform being registered with the Java runtime in its constructor. I'm not sure how you're measuring the time it's taking, but what you're probably seeing is the main page for the application being set and the renderer for it being initialized (which includes setting up and laying out all of the child elements and renderers of the main page of the application). For many applications, this is where the bulk of LoadApplication(new App()) is spent (though YMMV if you're doing a lot of database work or network stuff during startup).

  • DH80DH80 USMember ✭✭

    @EZHart it is a simple login screen with a stack, few entries and a button

    See this link

    ? Others are seeing the bulk of time here

  • EZHartEZHart USXamarin Team Xamurai

    @RinoJohnsen said:
    I would like to raise the question on UWP animations. ... The one thing we haven't been able to solve is the choppy animations on UWP.

    @RinoJohnsen I'm not seeing any UWP animation bugs in https://bugzilla.xamarin.com, but my search may have missed them. Do you have one open that I can point someone at? If not, could you open one? Be sure to include whether you're seeing this on phone/desktop, what hardware you're seeing it on, etc., and a reproduction project if possible.

    Thanks.

  • DH80DH80 USMember ✭✭

    @EZHart can android startup get better without AOT?

  • AbdullahNAAbdullahNA INMember ✭✭

    @EZHart I don't, however if you don't call "Migrate()" the app doesn't work. To utilize your db you need to call "Migrate()" all the time, that's how the EFCore() for SQLite is designed.

    Also, my main activity doesn't do anything that leverages db. I am just calling "Migrate()" on a different thread, that's all. So is my expectation NOT to impact the startup.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    excellent @EZHart . Thanks for your work

  • rogiheerogihee NLMember ✭✭✭

    @EZHart excellent answer. Any idea what the impact is of having lots of different assemblies to startup times? I try to minimize the amount of nugets used, but with a few plugins and the support libs an app easily grows to 20+ assemblies. Is this the reason why it is investigated to pull the whole of Xamarin.Forms into one dll?

  • huangjinshehuangjinshe USMember ✭✭✭
    edited April 2017

    You guys take too long time for this performance issue: Add RetainsRenderer option for page, improve page performance

    especially for UWP performance. The code getting older, for me It's hard to continue update and merge after so long time.

  • TonyDTonyD USMember ✭✭✭

    @rmarinho to get our metrics we use a couple of methods:

    1- Hierarchy viewer, Android - gives us total draw/layout time. We run it a few dozen times and get the average. However, more importantly, it shows us the generated views. You can run it by going to Tools -> Device Monitor in Xamarin Studio, then hitting hierarchy view.

    If you create a hello world app with XF and then with normal xamarin android, you'll see the tree depth is twice as deep in the XF version.

    2- Measure time for the main Content = view assignment. Start a stopwatch, do the content assignment, stop the stopwatch. We've also overriden OnLayout and OnMeasure to do a perf measurement as well.

    3- Overdraw measurement - you can toggle this on from the phone settings -> developer options -> show overdraw. I've yet to build a Xamarin Forms that didn't have at least 3x overdraw.

    That said we decided not to move to 2.3.5 yet since there were too many subtle UI regressions (especially with the keyboard and editable fields). We'll wait for that stuff to be resolved.

  • DavidOrtinauDavidOrtinau USForum Administrator, Xamarin Team, Insider, University Xamurai

    @TonyD would you please send me some details on the 2.3.5 regressions you're seeing? I'm scanning Bugzilla for 2.3.5 and don't see any reports about that.

  • BjornBBjornB USMember ✭✭✭
    edited May 2017

    @MigueldeIcaza https://github.com/xamarin/Xamarin.Forms/pull/897/commits/11d5359ac28025b8c42f2d95abdf033e5d707c8e

    This sounds very good! But can you provide some info other than "improves performance by 25x"?

    Will this be a noticable boost in rendertime if you have 99% of your layout colored with hex values?

  • DavidOrtinauDavidOrtinau USForum Administrator, Xamarin Team, Insider, University Xamurai

    @stevefoxover.5931 I messaged you to get more detail about those issues so we can fix them.

  • BenjaminFunkBenjaminFunk USMember ✭✭
    edited May 2017

    @AbdullahNA said:
    Android app startup is taking ~10 seconds. I am using Xamarin.Forms 2.3.4.x. It runs faster ~3 seconds on Android Emulator for Visual Studio, but it consistently takes ~10 seconds on real devices. I tested on the following devices (I am surprised the timing is almost same in debug as well as in the release mode).
    Test Results
    * ~8 to 10 seconds on Samsung Galaxy OnNXT
    * ~5-6 seconds on Xiaomi Mi Max Prime
    * ~4-5 seconds on Redmi Note 3
    * ~9.5 seconds on Asus Zenfone2

    I've cut off everything else that @AbdullahNA included in his post, but the big thing is Newtonsoft.Json. Initialization on that thing takes FOREVER the first time it has to deserialize something. And if that something is required to draw the UI, you can count on your device skipping frames. In the Android Emulator it's a relatively manageable 3-4 seconds, but on actual devices (I have a Moto Z Play to test on) it's locking up the UI upon its first call for close to 10 seconds. That same screen that locks up the first time runs fine the second time. Doesn't matter if it's a debug package or a release package, the sluggishness is always there.

    Since it's not a Xamarin package, it might be up to Newtonsoft to fix, but it's included by default in a new project so I thought it was worth mentioning here.

    I found the issue by using a debug package to write to the console line by line as it walked through the page setup from download through drawing the UI. When I search for "newtonsoft json slow android" I found this: http://stackoverflow.com/questions/42285254/json-net-slow-on-first-use-on-xamarin-android

  • DH_HA1DH_HA1 USMember ✭✭✭

    @BenjaminFunk I bet it is a lot of JIT compiling for Newtonsoft.Json. Try using AOT to see if this helps on release mode. Note it will bloat your APK size but it is a good test of how JIT affects your startup

  • BenjaminFunkBenjaminFunk USMember ✭✭

    Thanks for the suggestion, @DH_HA1. It did, as you said it would: make the storage requirement much larger (nearly double in size for the APK). Unfortunately it's not making a difference.

    The JSON record that's getting deserialized is pretty large if it contains an optional string with a base64-encoded image. But even if that image isn't present, the device locks up on the first load. Leave that screen and come back for another record (which still gets downloaded and deserialized) and it's fine.

    Just for fun, I gave it something to deserialize at startup. It fixed that page, but startup takes around 30 seconds and it's just a white screen while it starts up.

  • HenrySippHenrySipp USMember ✭✭
    edited May 2017

    My team is currently getting demolished by overhead in Android, pages can take up to a few seconds to load even with minimal layout. AOT helps this but not by much.

  • DH_HA1DH_HA1 USMember ✭✭✭

    @BenjaminFunk I would suggest doing the least amount possible on startup. Get a screen up and then show a loading image to load this data.

  • BenjaminFunkBenjaminFunk USMember ✭✭

    @DH_HA1 said:
    @BenjaminFunk I would suggest doing the least amount possible on startup. Get a screen up and then show a loading image to load this data.

    That's a good point. I've done this and now I have a nice logo screen, but it hasn't helped the time it takes to login since that page displays while everything spins up. And I can't put an activity indicator on that page, because it's just frozen, making the app look broken.

    I'm going to break this out into its own thread.

  • ChristianFalchChristianFalch NODeveloper Group Leader ✭✭✭

    I know I've talked a bit about AOT in this thread before, but I'm still not 100% done with the topic. Here are some pros and cons about using AOT on Android:

    Pros:
    - Startup speed is significantly increased
    - All subsequent JIT'ing of cold functions are avoided - instant speed

    Cons:
    - APK grows in size, depending on target architectures the apk can become really big
    - Compile time increases significantly

    Suggestion:
    Can the JIT'et code be cached on the device? This would lead to smaller apk's and only a hit from the JIT compiler the first time a function is called.

    From looking at the mono sources this seems to be possible using some switches and compiler magic. Anyone from the compiler/Android toolchain teams like to explain/elaborate on this?

  • EZHartEZHart USXamarin Team Xamurai

    @rogihee said:
    @EZHart excellent answer. Any idea what the impact is of having lots of different assemblies to startup times? I try to minimize the amount of nugets used, but with a few plugins and the support libs an app easily grows to 20+ assemblies. Is this the reason why it is investigated to pull the whole of Xamarin.Forms into one dll?

    Sorry for the late answer. I don't have great numbers on the overhead of loading many assemblies vs a few, but my suspicion is that it's small (but non-zero). The real startup issue is the time to JIT compile the code, and that's somewhat dependent on what code from those packages you actually use.

    If anyone does have some good data measuring the impact, I'd love to see it; it's difficult to measure, and someone else doing the work would save me a lot of time :smile:

    AFAIK, this wasn't the reason for investigating a single Xamarin.Forms DLL, though shaving a few fractions of a second off of the load time would be a nice side effect.

  • ChristianFalchChristianFalch NODeveloper Group Leader ✭✭✭

    @EZHart: When you say "The real startup issue is the time to JIT compile the code" - could you please elaborate on how JIT'ing is performed on Android (see my previous question) - Can JIT'ed code be cached on the device?

  • AdrianKnightAdrianKnight USMember ✭✭✭✭

    Forms is doing several other things for you, like setting up the deep linking provider, handling the status bar background, setting up handling for alerts and action sheets, toolbar support, and some other stuff I'm forgetting at the moment. And handling the API level checks and Forms abstractions, too. If you started adding all of these features to a plain Android app, the gap between startup times would start to close pretty fast.

    @EZHart I think it might be a good idea to let developers choose what to load at startup. As you mentioned, maybe some of these things can be lazy loaded until first use or loaded after the first page is rendered on the screen.

  • DH_HA1DH_HA1 USMember ✭✭✭

    @EZHart how big of a perf hit on startup to have Application Resources in the App.xaml?

  • EZHartEZHart USXamarin Team Xamurai

    @ChristianFalch said:
    @EZHart: When you say "The real startup issue is the time to JIT compile the code" - could you please elaborate on how JIT'ing is performed on Android (see my previous question) - Can JIT'ed code be cached on the device?

    Caching the JIT compilation results doesn't really make sense; the results would contain addresses which won't be correct on subsequent process restarts. Also, I suspect re-using JIT results would defeat some of the optimizations JIT compiler can make.

  • nikki00nikki00 ATMember

    There are some UI regressions from upgrading from 2.3.3 to 2.3.5 which we are trying to fix but once those are out we'll push our app to production and post some comprehensive numbers on perf improvements

  • JaredHJaredH AUMember ✭✭

    Unfortunately my team has found 2.3.5.239-pre3 to be significantly slower than 2.3.4.224 (the last release for us that compiles successfully for both Android and iOS). I added timing logic to two pages in our app - the home page and a read only style page with 93 labels and no input controls which I thought might make an interesting test. Note, we have no custom label renderers and I was using debug builds on a physical Android device not attached to the debugger.
    The home page was consistently 25% slower to construct and display, and the label heavy page ~40% slower. I restored the XF NuGet package back to 2.3.4, re-ran the tests, and was back to the original timings.
    I'm not sure if there's a go fast button we are meant to push, but we're disappointed with these results. The only positive we could draw on was that the iOS app builds successfully, unlike with 2.3.4.231 & 2.3.4.247.

  • ClayZuvichClayZuvich USMember ✭✭✭
    edited May 2017

    I've seen several posts about the latest Mono update slowing down Android apps. I can confirm this behavior, and I have found that Newtonsoft deserialization is where my issue is at. However, the slowdown only happens the first time an object is deserialized (for each unique class).

    I don't think it's related to Newtonsoft since it was working fine before, but I am positive others will start seeing this issue since it's pretty much the goto library.

    My gut tells me something has completely broken Reflection Android. Can anyone please confirm this behavior?

    I have the latest Forms release (2.3.4.247). Using Newtonsoft 10.0 is completely broken now on Android, so I downgraded to 8.0.3 and the performance is better.

Sign In or Register to comment.