0

Today, I was testing my app with large data (not quite large actually, 2000 records in total), and noticed that toObject() method is performing slow.

Basically, I get a list of records from firestore, process it to show in UI, and pass it to RecyclerView. To verify, I removed all of my processing logic and kept only toObject(). It is the bottleneck, taking approximately 9 seconds in total.

Here is my code:

public ArrayList<MyModel> doProcessing(Context context, QuerySnapshot snapshots) {
    ArrayList<MyModel> listToReturn = new ArrayList<>();

    for (DocumentSnapshot snap : snapshots.getDocuments()) {
        MyModel myModel = snap.toObject(MyModel.class);

        ...
        ...   // my processing logic
        ...   // check the data and set other fields of myModel based on it 
        ...

        listToReturn.add(myModel);
    }

    return listToReturn;
}

Here is a screenshot of MyModel schema(?!). It is not that heavy.

screenshot

How to work around this? Anybody experiencing the same issue?

Mangesh
  • 5,491
  • 5
  • 48
  • 71
  • Did you use the profiler to check for this call statics? I think the problem is not in the toObject but instead on the time taken to do the query, maybe your internet connection ? – Gastón Saillén Jun 09 '20 at 14:31
  • Yes I checked it. Query finishes within a second. No network issue. – Mangesh Jun 09 '20 at 14:46

1 Answers1

4

The first call to toObject() for a given class is always going to be slow, and it will never match custom written code. That's because it's using Java reflection to discover the names of methods and properties on the class object so that it can map document fields into them. Reflection is known to be very slow. If you don't want that slowness, you should instead use getData() on the snapshot to get a Map<String, Object> of field values, and manually map the values into your data object.

Basically, you have to decide if you want convenience or performance.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Thanks! That clears a lot. Just one thing I didn't understand. If first call takes x time and subsequent calls take y, then total should be x+(y\*n), n being number of docs. But in my experiments, it is x\*n. Essentially, every call seems slower. – Mangesh Jun 09 '20 at 17:57
  • That sounds like a completely different issue. Without understanding how your app holistically, it's not really possible to say what's going on. I've not heard of anyone observing like that before. – Doug Stevenson Jun 09 '20 at 18:15