firebase-ios-sdk icon indicating copy to clipboard operation
firebase-ios-sdk copied to clipboard

Firestore.Decoder is slow compared to JSONDecoder

Open collinhundley opened this issue 4 months ago • 7 comments

Description

Decoding an array of QuerySnapshotDocument using Firestore.Decoder is very slow, compared to decoding a similar array using JSONDecoder:

// 50k documents
let documents = try await myCollection.getDocuments().documents
// Avg 9.6s decode
let items = documents.compactMap{try? $0.data(as: Item.self)}

// Same 50k items
let data = try JSONEncoder().encode(items)
// Avg 2.4s decode
let result = try JSONDecoder().decode([Item].self, from: data)

What's more is that we don't gain any performance from parallelization. For example, if we split documents into 10 arrays of 5k documents each, and initialize one Firestore.Decoder for each group:

let items = await withTaskGroup(of: [Item].self) { group in
    // chunkedDocuments: [[QueryDocumentSnapshot]]
    for chunk in chunkedDocuments {
        group.addTask { 
            let decoder = Firestore.Decoder()
            return chunk.compactMap{try? $0.data(as: Item.self, decoder: decoder)}
        }
    }
    var items = [Item]()
    for await result in group {
        items.append(contentsOf: result)
    }
    return items
}

...the total time is worse: about 10.3s.

So there are 2 issues:

  1. Why is Firestore.Decoder 4x slower than JSONDecoder?
  2. Does Firestore.Decoder utilize some shared internal state that prevents instances from running independently on different threads?

Reproducing the issue

No response

Firebase SDK Version

10.29

Xcode Version

16

Installation Method

Swift Package Manager

Firebase Product(s)

Firestore

Targeted Platforms

iOS, macOS

Relevant Log Output

No response

If using Swift Package Manager, the project's Package.resolved

Expand Package.resolved snippet

Replace this line with the contents of your Package.resolved.

If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet

Replace this line with the contents of your Podfile.lock!

collinhundley avatar Oct 08 '24 20:10 collinhundley