Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOURCE DiskCacheStrategy faster to display than RESULT #281

Closed
mttmllns opened this issue Nov 27, 2014 · 3 comments

Comments

Projects
None yet
3 participants
@mttmllns
Copy link

commented Nov 27, 2014

We just started using Glide and I've been comparing the default RESULT disk cache strategy vs. SOURCE and I'm noticing that SOURCE is noticeably faster to render a newly net-retrieved image to the screen.

I'm playing with two second-gen Nexus 7's with Lollipop side-by-side with images ~200K, 700x700 average. I made the most minimal example I can and have ~100 images in a vanilla RecyclerView with a LinearLayoutManager where 4-5 images will be visible on screen at a time. If I start up both configurations from scratch and scroll to the very bottom of the view the SOURCE config finishes showing the images in less than a second whereas the RESULT config finishes showing them in 2-4 seconds. This is consistent with regular scrolling where images come down one at a time: SOURCE is always faster than RESULT.

Without diving in too deep into the code myself I'm suspecting that RESULT resizes the image before it shows it on screen. I'd imagine you could make it as fast as SOURCE if on the first/network retrieval you immediately show the full image in the view like SOURCE but on a background thread continue resizing the image and store it in the disk cache resized so on the second request it shows up resized.

And now that I've actually typed all that out I can see how that might be unexpected for someone not using something like fitCenter() where the difference between SOURCE and RESULT looks almost the same on screen...hmmm.

Does this use case sound interesting to you, though? I assume there're probably extension points where I could create the behavior I want using custom targets or something but I do really like how Glide handles all the view/adapter/recycling stuff behind the curtains for me.

Any suggestions for how to accomplish this with existing apis or if this is a valid enhancement request?

Thanks much!

Details:

RecyclerView.Adapter

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Glide.with(holder.itemView.getContext())
            .load(thumbnails[position])
            .fitCenter()
            .crossFade()
//          .diskCacheStrategy(DiskCacheStrategy.SOURCE)
            .into(holder.image);
}

View Layout

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:scaleType="centerCrop"
    android:background="#444444"
    android:layout_marginBottom="10dp" />
@sjudd

This comment has been minimized.

Copy link
Member

commented Nov 27, 2014

This is a pretty complex question, so forgive me if I miss something.

First, I believe the feature request you mention (display, then cache for RESULT) is already open: #150. I agree it would be a great feature, it's slightly complex because of resource re-use.

Second, SOURCE and RESULT will both produce the same image, especially on the first load. Even if we were to implement #150, the transformation would still happen before the image was returned to the requestor.

Third, the transformation itself is very fast, it's mostly decoding and encoding that take time.

Finally, a bunch of things factor in to how long it takes to cache images in both RESULT and SOURCE, and you may want to consider more than initial load speed depending on your use case:

The the speed of the encode for RESULT depends a lot on the type of images you're loading. There's a rough order to it:

  1. JPEGs are fastest to encode, we just use Bitmap.compress which is reasonably well optimized.
  2. PNGs/TIFFs that have alpha are around 10x slower than JPEGs for the same image size, but they preserve alpha. I don't think this encode path is particularly well optimized.
  3. GIFs are very slow to encode.

Size also plays an important role. RESULT caches transformed images, so if you're downloading very large images, but displaying them in relatively small views, RESULT may be faster because you have fewer pixels to write to disk. Some of this win is offset by the time to encode the image which even for JPEGs will be slower per pixel that just writing data to disk.

If you load the same transformed images repeatedly, although RESULT may be slower for the first load, it will almost certainly be faster for subsequent loads because you're loading and decoding fewer bytes/pixels.

RESULT will also result in fewer bytes used on the sd card for transformed images.

TLDR: For GIFs, you probably always want to use SOURCE. For other formats, I'd lean toward RESULT if you view images repeatedly or retrieve (local or remote) large images and display them in small views, and toward SOURCE if you tend to view images once, or you apply only a small transformation.

Hope this helps.

@mttmllns

This comment has been minimized.

Copy link
Author

commented Dec 2, 2014

Yes #150 sounds like the ticket. Didn't see that one. Feel free to close this as a duplicate request, then!

Thanks for the clarification re: transformation vs. encoding/decoding. Makes perfect sense.

Definitely understand about the pros/cons of RESULT vs. SOURCE based on use-cases. I'm in an investigative mode right now so just trying everything I can and comparing/contrasting. Thanks for the details re: JPEG/PNG/GIF.

@sjudd

This comment has been minimized.

Copy link
Member

commented Dec 2, 2014

Great, no problem, glad it helped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.