firebase / firebase/firebase-ios-sdk

Firestore.Decoder is slow compared to JSONDecoder

Open
#13,849 7 comments 0 reactions 1 assignee Claimed by @MarkDuckworth View on GitHub
api: firestore Swift API type: feature request
Dominant language
C++
Stars
6.7k
Forks
1.8k
Avg merge
2d 14h
Merged PRs (30d)
72

Description

### Description

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

```swift
// 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:

```swift
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

```json

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

```

### If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet

```yml

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

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.