alexstyl/contactstore

Feature Request: Provide Paging-Support

fgubler opened this issue ยท 9 comments

When you have a lot of contacts, loading them all at once can take some time. For that reason, I would like to use paging.
Therefore it would be really nice if a method could be provided which may look a bit like this:

    public fun fetchContactsPaged(
        predicate: ContactPredicate? = null,
        columnsToFetch: List<ContactColumn> = emptyList(),
        displayNameStyle: DisplayNameStyle = DisplayNameStyle.Primary,
        pageSize: Int,
        offset: Int,
    ): FetchRequest<List<Contact>>

allowing the caller to pass a page size (how many records should be fetched) and an offset (assuming the contacts are sorted by displayName).

Thanks for the feature request. Could you kindly share some numbers? What is the number of contacts you are trying to process?

Thanks for the reply :-).
Of course: My test data-set were around 500-600 contacts which took around 12s to load on my test-device.
The query I sent asked for the Name-columns.

For context: I am currently using my old phone (Android 7) for development so part of the "long" duration is surely due to old hardware but still, showing a loading screen to the user for 12s is not ideal :-).
If it helps, I can also test it on newer devices to get some more data-points.

12s is really not good. Any chance you can give me the specs of the device?

A quick test on a newer device with the same contacts would be fantastic too

Sure thing

  • It is a Sony Xperia Z5 Compact (E5823), Snapdragon 810 (8-core), 2GB RAM, Android 7.1.1 => 12s
  • Newer device 1: Sony Xperia XZ2 Compact (E8324), Snapdragon 845 (8-core), 4 GB RAM, Android 10 => 4.6s - 5s
  • Newer device 2: Samsung Galaxy S22 => 9s

So in conclusion: there seem to be large differences between the devices and some of them quite unexpected
(strange that the much newer S22 would be slower than the Sony one which is around 3.5 years old)

Just noticed something: If I just do a plain fetch() without the columnsToFetch = listOf(ContactColumn.Names), performance is now issue at all: around 400ms instead of 12s for the oldest device.
So it is still curious why the difference should be so huge. But for now, I will try to adjust my code to just work with the display-value in the overview-screen.

I think I understand what is happening.

I am suspecting that you are trying to load multiple contacts at once (specifying no predicate), and requesting one or more contact columns. Each contact column you request will cause additional queries to take place, which will slow down the fetch().

Try the following:

Are you fetching details for a contact list kind of screen? Then you should fetch no columns at all and the performance will be the best you can get. You do not need ContactColumn.Names for this case, as you can use contact.displayname. Also, you do not need ContactColumn.Image as you can use contact.thumbnailUri to load the thumbnails.

If you are loading details for a a contact details screen, that should be when you should be fetching any specific columns.

Does this make sense for your use case? If you can let me know your exact use case, I can help you out further.

Yes that is the case and makes sense.
Yes it is for the contact-list screen, so I will avoid ContactColumn.Names and just use displayname, thanks ๐Ÿ‘
I anyway load the details for the detail-screen later when I just have to do it for 1 contact. I just thought, I needed the Names from the beginning.

That should solve the problem: thanks a lot for the help :-).

PS: in case you were wondering, my use-case is this: https://github.com/fgubler/PrivateContacts

PrivateContacts look cool

I can see the confusion about the contact columns. I will make sure to document this behavior as this is something currently missing.

Again, thank you for openning this issue ๐Ÿ‘

Thanks for the help ๐Ÿ˜ƒ. Works like a charm, now.