Skip to content

Firestore.Decoder is slow compared to JSONDecoder #13849

Open
@collinhundley

Description

@collinhundley

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!

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions