Code Monkey home page Code Monkey logo

Comments (8)

mlykotom avatar mlykotom commented on May 25, 2024 1

There's a couple of problems measuring the timing this way:

  1. In general, you shouldn't measure performance on emulator as this way you effectively measure how powerful hosting machine you have
  2. This way, you are can be hitting all the system caches, which doesn't show in the real app.

What I did to benchmak this, was using Macrobenchmark in the real app with StartupMode.COLD to see the worst-case scenario.

For 10 iterations, I see these results

NiaImageLoaderMs                        min     2.0,   median     4.2,   max     6.9
Traces: Iteration 0 1 2 3 4 5 6 7 8 9

I further started digging into what's happening and I think I know now.

I followed you advice to only have OkHttp asynchronously, but keep the ImageLoader on-demand and this is what I see in the traces.

When the first image is shown on screen (in NIA it's the SingleTopicButton), it starts to initialize Coil, which takes ~7ms.
If this was during startup, it wouldn't be much of an issue, but with a first composition, it might be problematic (trace here).

image

The cause are (my hypothesis) the binder transaction sections, which comes from the SystemCallbacks.

I think Coil should be able to register the system services on a Default thread to prevent the initialization hit and then it won't matter when the ImageLoader is actually initialized.

from coil.

colinrtwhite avatar colinrtwhite commented on May 25, 2024 1

Fixed here in the 3.x release. I'll also backport the change to the next release, 2.6.0.

I tried running my own macrobenchmark test after the changes, but the initialization method didn't appear in the measured methods.

from coil.

mlykotom avatar mlykotom commented on May 25, 2024 1

Awesome! Thanks! 🎉

If you'd like to help diagnose the macrobenchmark tests, maybe ping me on ASG?

from coil.

colinrtwhite avatar colinrtwhite commented on May 25, 2024

It looks like you were initializing your OkHttpClient eagerly here, which slowed down the ImageLoader creation. Coil already supports lazy initialization of the OkHttpClient using the ImageLoader.Builder.callFactory { } function that accepts a callback that'll be invoked on a background thread. By default it'll create the OkHttpClient using that method.

newImageLoader is invoked the first time Coil.imageLoader() is called, which is generally on the main thread, but doesn't have to be. I don't think we should eagerly asynchronously initialize the singleton ImageLoader for a couple reasons:

  • ImageLoaders are cheap to initialize (see benchmark below).
  • Eagerly initializing the ImageLoader would require importing androidx.startup.
  • We wouldn't be able to eagerly initialize on non-Android platforms so the behaviour wouldn't be consistent.
  • Eagerly initializing would create a race condition if the user uses Coil.setImageLoader before the first Coil.imageLoader call.

For docs, I'd be open to a PR that improves this!

from coil.

colinrtwhite avatar colinrtwhite commented on May 25, 2024

I ran a quick benchmark on a Pixel 7 emulator and an ImageLoader with default arguments takes 0.1 milliseconds to initialize. The result is similar when using ImageLoader.Builder.callFactory { }. Here's the code:

val iterations = 1_000
var sum = 0L
var imageLoader: ImageLoader?
repeat(iterations) {
    sum += measureNanoTime {
        imageLoader = ImageLoader(context)
    }
    imageLoader?.shutdown()
}
println("BENCHMARK OUTPUT: ${sum / iterations.toDouble()}")

from coil.

mlykotom avatar mlykotom commented on May 25, 2024

When I set .networkObserverEnabled(false), then the initialization drops to ~1.5ms. (trace)
image

from coil.

colinrtwhite avatar colinrtwhite commented on May 25, 2024

Ah thanks for digging in! Agreed - SystemCallbacks should be registered lazily on a background thread. We should be able to delay checking if the device has a suitable network connection until we're on a background thread and move the network callbacks + memory callbacks registration to a background thread.

from coil.

yschimke avatar yschimke commented on May 25, 2024

PR for a cautionary fix on OkHttp 5.x

https://github.com/square/okhttp/pull/8248/files

from coil.

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.