Skip to content

Instantly share code, notes, and snippets.

@raphlinus
Created December 29, 2017 19:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raphlinus/3d80ab00eed7cd2690b14b7b686938ee to your computer and use it in GitHub Desktop.
Save raphlinus/3d80ab00eed7cd2690b14b7b686938ee to your computer and use it in GitHub Desktop.
Simple JSON task using new Decodable protocol
// Copyright 2017 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import Foundation
var baseTs: UInt64 = 0
func ts(_ label: String) {
let ts = mach_absolute_time()
print(label + String(format: ": %.3f", Double(ts - baseTs) * 1e-6))
}
let data = try Data(contentsOf: URL(fileURLWithPath: "/tmp/update.json"))
struct Req: Decodable {
var method: String
var params: Params
}
struct Params: Decodable {
var viewId: String
var update: Update
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.viewId = try container.decode(String.self, forKey: .viewId)
self.update = try container.decode(Update.self, forKey: .update)
}
enum CodingKeys: String, CodingKey {
case viewId = "view_id"
case update
}
}
struct Update: Decodable {
var ops: [Op]
var pristine: Bool
}
struct Op: Decodable {
var op: String
var n: Int
var lines: [Line]?
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.op = try container.decode(String.self, forKey: .op)
self.n = try container.decode(Int.self, forKey: .n)
self.lines = try container.decodeIfPresent(Array<Line>.self, forKey: .lines)
}
enum CodingKeys: String, CodingKey {
case op
case n
case lines
}
}
struct Line: Decodable {
var text: String
var styles: [Int]
}
func benchNewJson() throws {
baseTs = mach_absolute_time()
let jsonDecoder = JSONDecoder()
ts("created decoder")
let obj = try jsonDecoder.decode(Req.self, from: data)
ts("decoded")
var total = 0
var textLen = 0
for op in obj.params.update.ops {
total += op.n
if let lines = op.lines {
for line in lines {
textLen += line.text.count
}
}
}
ts("after traversal")
print("Decodable result:", total, textLen)
}
try benchNewJson()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment