Skip to content

Commit 0209a2d

Browse files
authored
Merge pull request eu-digital-green-certificates#3 from martinreichart/feature/performance
Massive performance improvements by switching from using Data to ArraySlice
2 parents c7eb7d0 + 257f6ba commit 0209a2d

File tree

4 files changed

+27
-21
lines changed

4 files changed

+27
-21
lines changed

Sources/SwiftCBOR/Decoder/CodableCBORDecoder.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ final public class CodableCBORDecoder {
99
public var userInfo: [CodingUserInfoKey : Any] = [:]
1010

1111
public func decode<T: Decodable>(_ type: T.Type, from data: Data) throws -> T {
12+
return try decode(type, from: ArraySlice([UInt8](data)))
13+
}
14+
15+
public func decode<T: Decodable>(_ type: T.Type, from data: ArraySlice<UInt8>) throws -> T {
1216
let decoder = _CBORDecoder(data: data)
1317
decoder.userInfo = self.userInfo
1418
if type == Date.self {
@@ -38,15 +42,16 @@ final class _CBORDecoder {
3842
var userInfo: [CodingUserInfoKey : Any] = [:]
3943

4044
var container: CBORDecodingContainer?
41-
fileprivate var data: Data
45+
fileprivate var data: ArraySlice<UInt8>
4246

43-
init(data: Data) {
47+
init(data: ArraySlice<UInt8>) {
4448
self.data = data
4549
}
4650
}
4751

4852
extension _CBORDecoder: Decoder {
4953
func container<Key: CodingKey>(keyedBy type: Key.Type) -> KeyedDecodingContainer<Key> {
54+
5055
let container = KeyedContainer<Key>(data: self.data, codingPath: self.codingPath, userInfo: self.userInfo)
5156
self.container = container
5257

@@ -73,7 +78,7 @@ protocol CBORDecodingContainer: class {
7378

7479
var userInfo: [CodingUserInfoKey : Any] { get }
7580

76-
var data: Data { get set }
81+
var data: ArraySlice<UInt8> { get set }
7782
var index: Data.Index { get set }
7883
}
7984

@@ -90,7 +95,7 @@ extension CBORDecodingContainer {
9095
}
9196
defer { self.index = nextIndex }
9297

93-
return self.data.subdata(in: self.index..<nextIndex)
98+
return Data(Array(self.data[self.index..<(nextIndex)]))
9499
}
95100

96101
func read<T: FixedWidthInteger>(_ type: T.Type) throws -> T {

Sources/SwiftCBOR/Decoder/KeyedDecodingContainer.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ extension _CBORDecoder {
6666
}
6767
}()
6868

69-
var data: Data
69+
var data: ArraySlice<UInt8>
7070
var index: Data.Index
7171
var codingPath: [CodingKey]
7272
var userInfo: [CodingUserInfoKey: Any]
7373

74-
init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
74+
init(data: ArraySlice<UInt8>, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
7575
self.codingPath = codingPath
7676
self.userInfo = userInfo
7777
self.data = data

Sources/SwiftCBOR/Decoder/SingleValueDecodingContainer.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ extension _CBORDecoder {
44
final class SingleValueContainer {
55
var codingPath: [CodingKey]
66
var userInfo: [CodingUserInfoKey: Any]
7-
var data: Data
7+
var data: ArraySlice<UInt8>
88
var index: Data.Index
99

10-
init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
10+
init(data: ArraySlice<UInt8>, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
1111
self.codingPath = codingPath
1212
self.userInfo = userInfo
1313
self.data = data

Sources/SwiftCBOR/Decoder/UnkeyedDecodingContainer.swift

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extension _CBORDecoder {
1010

1111
var userInfo: [CodingUserInfoKey: Any]
1212

13-
var data: Data
13+
var data: ArraySlice<UInt8>
1414
var index: Data.Index
1515

1616
lazy var count: Int? = {
@@ -35,7 +35,7 @@ extension _CBORDecoder {
3535
// decoding each item in the array.
3636
let nextIndex = self.data.startIndex.advanced(by: 1)
3737
let remainingData = self.data.suffix(from: nextIndex)
38-
return try? CBORDecoder(input: remainingData.map { $0 }).readUntilBreak().count
38+
return try? CBORDecoder(input: remainingData).readUntilBreak().count
3939
default:
4040
return nil
4141
}
@@ -70,8 +70,8 @@ extension _CBORDecoder {
7070

7171
return nestedContainers
7272
}
73-
74-
init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
73+
74+
init(data: ArraySlice<UInt8>, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
7575
self.codingPath = codingPath
7676
self.userInfo = userInfo
7777
self.data = data
@@ -96,6 +96,7 @@ extension _CBORDecoder {
9696
}
9797

9898
extension _CBORDecoder.UnkeyedContainer: UnkeyedDecodingContainer {
99+
99100
func decodeNil() throws -> Bool {
100101
try checkCanDecodeValue()
101102
defer { self.currentIndex += 1 }
@@ -171,16 +172,16 @@ extension _CBORDecoder.UnkeyedContainer {
171172
case 0x40...0x57:
172173
length = try CBORDecoder(input: [0]).readLength(format, base: 0x40)
173174
case 0x58:
174-
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1)).map { $0 }
175+
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1))
175176
length = try CBORDecoder(input: remainingData).readLength(format, base: 0x40) + 1
176177
case 0x59:
177-
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1)).map { $0 }
178+
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1))
178179
length = try CBORDecoder(input: remainingData).readLength(format, base: 0x40) + 2
179180
case 0x5a:
180-
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1)).map { $0 }
181+
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1))
181182
length = try CBORDecoder(input: remainingData).readLength(format, base: 0x40) + 4
182183
case 0x5b:
183-
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1)).map { $0 }
184+
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1))
184185
length = try CBORDecoder(input: remainingData).readLength(format, base: 0x40) + 8
185186
// Terminated by break
186187
case 0x5f:
@@ -190,16 +191,16 @@ extension _CBORDecoder.UnkeyedContainer {
190191
case 0x60...0x77:
191192
length = try CBORDecoder(input: [0]).readLength(format, base: 0x60)
192193
case 0x78:
193-
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1)).map { $0 }
194+
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1))
194195
length = try CBORDecoder(input: remainingData).readLength(format, base: 0x60) + 1
195196
case 0x79:
196-
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1)).map { $0 }
197+
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1))
197198
length = try CBORDecoder(input: remainingData).readLength(format, base: 0x60) + 2
198199
case 0x7a:
199-
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1)).map { $0 }
200+
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1))
200201
length = try CBORDecoder(input: remainingData).readLength(format, base: 0x60) + 4
201202
case 0x7b:
202-
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1)).map { $0 }
203+
let remainingData = self.data.suffix(from: startIndex.advanced(by: 1))
203204
length = try CBORDecoder(input: remainingData).readLength(format, base: 0x60) + 8
204205
// Terminated by break
205206
case 0x7f:
@@ -244,7 +245,7 @@ extension _CBORDecoder.UnkeyedContainer {
244245
let range: Range<Data.Index> = startIndex..<self.index.advanced(by: length)
245246
self.index = range.upperBound
246247

247-
let container = _CBORDecoder.SingleValueContainer(data: self.data.subdata(in: range), codingPath: self.codingPath, userInfo: self.userInfo)
248+
let container = _CBORDecoder.SingleValueContainer(data: self.data[range.startIndex..<(range.endIndex)], codingPath: self.codingPath, userInfo: self.userInfo)
248249

249250
return container
250251
}

0 commit comments

Comments
 (0)