Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.

Commit 7391888

Browse files
committed
Merge bug/performanceIssues into develop
2 parents 741e022 + 4e08dca commit 7391888

14 files changed

+1033
-1043
lines changed

JSON.xcodeproj/project.pbxproj

+141-20
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>classNames</key>
6+
<dict>
7+
<key>JSONPerformanceTests</key>
8+
<dict>
9+
<key>testParsePerformanceWithLargeJson()</key>
10+
<dict>
11+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
12+
<dict>
13+
<key>baselineAverage</key>
14+
<real>1.733</real>
15+
<key>baselineIntegrationDisplayName</key>
16+
<string>Local Baseline</string>
17+
</dict>
18+
</dict>
19+
<key>testParsePerformanceWithLargeJsonNSJSONSerialization()</key>
20+
<dict>
21+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
22+
<dict>
23+
<key>baselineAverage</key>
24+
<real>0.78183</real>
25+
<key>baselineIntegrationDisplayName</key>
26+
<string>Local Baseline</string>
27+
</dict>
28+
</dict>
29+
<key>testSerializerSpeedNSJSONSerialization()</key>
30+
<dict>
31+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
32+
<dict>
33+
<key>baselineAverage</key>
34+
<real>1.1673</real>
35+
<key>baselineIntegrationDisplayName</key>
36+
<string>Local Baseline</string>
37+
</dict>
38+
</dict>
39+
<key>testSerializerSpeedPrettyPrinting()</key>
40+
<dict>
41+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
42+
<dict>
43+
<key>baselineAverage</key>
44+
<real>1.5673</real>
45+
<key>baselineIntegrationDisplayName</key>
46+
<string>Local Baseline</string>
47+
</dict>
48+
</dict>
49+
<key>testVDKAParsePerformanceWithLargeJson()</key>
50+
<dict>
51+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
52+
<dict>
53+
<key>baselineAverage</key>
54+
<real>1.282</real>
55+
<key>baselineIntegrationDisplayName</key>
56+
<string>Local Baseline</string>
57+
</dict>
58+
</dict>
59+
<key>testVDKASerializerSpeed()</key>
60+
<dict>
61+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
62+
<dict>
63+
<key>baselineAverage</key>
64+
<real>1.098</real>
65+
<key>baselineIntegrationDisplayName</key>
66+
<string>Local Baseline</string>
67+
</dict>
68+
</dict>
69+
</dict>
70+
</dict>
71+
</dict>
72+
</plist>

JSON.xcodeproj/xcshareddata/xcbaselines/AA853ADC1CBE366500FD3970.xcbaseline/Info.plist

+31
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,37 @@
3535
<string>com.apple.platform.iphonesimulator</string>
3636
</dict>
3737
</dict>
38+
<key>EB8DF2B7-7AB3-4CB4-8EBC-9AE5D1E982CA</key>
39+
<dict>
40+
<key>localComputer</key>
41+
<dict>
42+
<key>busSpeedInMHz</key>
43+
<integer>100</integer>
44+
<key>cpuCount</key>
45+
<integer>1</integer>
46+
<key>cpuKind</key>
47+
<string>Intel Core i5</string>
48+
<key>cpuSpeedInMHz</key>
49+
<integer>2500</integer>
50+
<key>logicalCPUCoresPerPackage</key>
51+
<integer>4</integer>
52+
<key>modelCode</key>
53+
<string>MacBookPro10,2</string>
54+
<key>physicalCPUCoresPerPackage</key>
55+
<integer>2</integer>
56+
<key>platformIdentifier</key>
57+
<string>com.apple.platform.macosx</string>
58+
</dict>
59+
<key>targetArchitecture</key>
60+
<string>x86_64</string>
61+
<key>targetDevice</key>
62+
<dict>
63+
<key>modelCode</key>
64+
<string>iPhone8,1</string>
65+
<key>platformIdentifier</key>
66+
<string>com.apple.platform.iphonesimulator</string>
67+
</dict>
68+
</dict>
3869
</dict>
3970
</dict>
4071
</plist>

JSON.xcodeproj/xcshareddata/xcschemes/JSONPerformanceTests.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
</BuildActionEntries>
2424
</BuildAction>
2525
<TestAction
26-
buildConfiguration = "Debug"
26+
buildConfiguration = "Release"
2727
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
2929
shouldUseLaunchSchemeArgsEnv = "YES">

JSONPerformanceTests/JSONPerformanceTests.swift

+48-88
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,67 @@
11

22
import XCTest
3-
@testable import JSON
3+
import JSON
4+
5+
let json: JSON = {
6+
print("Generating jsonString")
7+
8+
let numElements = 100_000
9+
let arc4random_max: UInt64 = 0x100000000
10+
11+
func randomNumber() -> Double { return Double(arc4random()) / Double(arc4random_max) }
12+
13+
func randomName() -> String {
14+
var str = ""
15+
let chars = Array("abcdefghijklmnopqrstuvwxyz".characters)
16+
for _ in 0...5 {
17+
let char = chars[Int(arc4random_uniform(UInt32(chars.count)))]
18+
str.append(char)
19+
}
20+
str.appendContentsOf(" ")
21+
str.appendContentsOf(arc4random_uniform(10000).description)
22+
return str
23+
}
24+
25+
var arr: [JSON] = []
26+
27+
for _ in 0..<numElements {
28+
arr.append(
29+
[
30+
"x": randomNumber(),
31+
"y": randomNumber(),
32+
"z": randomNumber(),
33+
"name": randomName(),
34+
"opts": [
35+
"1": [1, true] as JSON
36+
] as JSON
37+
] as JSON
38+
)
39+
}
40+
print("Done generating jsonString")
41+
42+
return ["coordinates": arr.encoded(), "info": "some info"]
43+
}()
444

545
class JSONPerformanceTests: XCTestCase {
646

747

848
override func setUp() {
949
super.setUp()
1050

11-
json = {
12-
print("Generating jsonString")
13-
14-
let numElements = 10_000
15-
let arc4random_max = 0x100000000
16-
17-
func randomNumber() -> Double { return Double(arc4random()) / Double(arc4random_max) }
18-
19-
func randomName() -> String {
20-
var str = ""
21-
let chars = Array("abcdefghijklmnopqrstuvwxyz".characters)
22-
for _ in 0...5 {
23-
let char = chars[Int(arc4random_uniform(UInt32(chars.count)))]
24-
str.append(char)
25-
}
26-
str.appendContentsOf(" ")
27-
str.appendContentsOf(arc4random_uniform(10000).description)
28-
return str
29-
}
30-
31-
var arr: [JSON] = []
32-
33-
for _ in 0..<numElements {
34-
arr.append(
35-
[
36-
"x": randomNumber(),
37-
"y": randomNumber(),
38-
"z": randomNumber(),
39-
"name": randomName(),
40-
"opts": [
41-
"1": [1, true] as JSON
42-
] as JSON
43-
] as JSON
44-
)
45-
}
46-
print("Done generating jsonString")
47-
48-
return ["coordinates": arr.encoded(), "info": "some info"]
49-
}()
50-
51-
jsonString = try! JSONSerializer.serialize(json)
51+
jsonString = try! JSON.Serializer.serialize(json)
5252

5353
let jsonArray: JSON = .array((100_000..<200_000).map({ i in JSON(i) }))
5454
largeJsonArray = try! jsonArray.serialized()
5555
}
5656

57-
var json: JSON!
5857
var jsonString: String!
5958
var largeJsonArray: String!
6059

61-
func testParsePerformanceWithLargeJson() {
60+
func testVDKAParsePerformanceWithLargeJson() { // VDKAParser
6261

6362
measureBlock {
6463
do {
65-
self.json = try JSONParser.parse(self.jsonString)
64+
try JSON.Parser.parse(self.jsonString)
6665
} catch {
6766
if let printableError = error as? CustomStringConvertible {
6867
XCTFail("JSON parse error: \(printableError)")
@@ -71,7 +70,7 @@ class JSONPerformanceTests: XCTestCase {
7170
}
7271
}
7372

74-
func testParsePerformanceWithLargeJsonNSJSONSerialization() {
73+
func testParsePerformanceWithLargeJsonNSJSONSerialization() { // Apple
7574

7675
let data = jsonString.dataUsingEncoding(NSUTF8StringEncoding)!
7776

@@ -86,49 +85,10 @@ class JSONPerformanceTests: XCTestCase {
8685
}
8786
}
8887

89-
func testParseSimple10KeyPairObject() {
90-
let tenKeyJson = try! ([
91-
"abcde": 1,
92-
"yerea": "ueiro",
93-
"leida": false,
94-
"iweur": true,
95-
"cnale": 9324,
96-
"awier": 839.4,
97-
"weiru": -1.0,
98-
"eiruaa": "12311238jf",
99-
"ljasdflkj": true,
100-
"ewkrjl": "qelrkjl"
101-
] as JSON).serialized()
102-
103-
measureBlock {
104-
do {
105-
for _ in 0..<10000 {
106-
try JSONParser.parse(tenKeyJson)
107-
}
108-
} catch {
109-
if let printableError = error as? CustomStringConvertible {
110-
XCTFail("JSON parse error: \(printableError)")
111-
}
112-
}
113-
}
114-
}
115-
116-
func testParseLargeJsonArray() {
117-
measureBlock {
118-
do {
119-
try JSONSerializer.serialize(self.largeJsonArray!)
120-
} catch {
121-
if let printableError = error as? CustomStringConvertible {
122-
XCTFail("JSON parse error: \(printableError)")
123-
}
124-
}
125-
}
126-
}
127-
128-
func testSerializerSpeed() {
88+
func testVDKASerializerSpeed() {
12989
measureBlock {
13090
do {
131-
try JSONSerializer.serialize(self.json!)
91+
try JSON.Serializer.serialize(json)
13292
} catch {
13393
if let printableError = error as? CustomStringConvertible {
13494
XCTFail("JSON parse error: \(printableError)")
@@ -154,7 +114,7 @@ class JSONPerformanceTests: XCTestCase {
154114
func testSerializerSpeedPrettyPrinting() {
155115
measureBlock {
156116
do {
157-
try JSONSerializer.serialize(self.json!, options: [.prettyPrint])
117+
try JSON.Serializer.serialize(json, options: [.prettyPrint])
158118
} catch {
159119
if let printableError = error as? CustomStringConvertible {
160120
XCTFail("JSON parse error: \(printableError)")

Profiling/main.swift

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//
2+
// main.swift
3+
// Profiling
4+
//
5+
// Created by Ethan Jackwitz on 4/20/16.
6+
// Copyright © 2016 Ethan Jackwitz. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
let json: JSON = {
12+
print("Generating jsonString")
13+
14+
let numElements = 100_000
15+
let arc4random_max = 0x100000000
16+
17+
func randomNumber() -> Double { return Double(arc4random()) / Double(arc4random_max) }
18+
19+
func randomName() -> String {
20+
var str = ""
21+
let chars = Array("abcdefghijklmnopqrstuvwxyz".characters)
22+
for _ in 0...5 {
23+
let char = chars[Int(arc4random_uniform(UInt32(chars.count)))]
24+
str.append(char)
25+
}
26+
str.appendContentsOf(" ")
27+
str.appendContentsOf(arc4random_uniform(10000).description)
28+
return str
29+
}
30+
31+
var arr: [JSON] = []
32+
33+
for _ in 0..<numElements {
34+
arr.append(
35+
[
36+
"x": randomNumber(),
37+
"y": randomNumber(),
38+
"z": randomNumber(),
39+
"name": randomName(),
40+
"opts": [
41+
"1": [1, true] as JSON
42+
] as JSON
43+
] as JSON
44+
)
45+
}
46+
print("Done generating jsonString")
47+
48+
return ["coordinates": arr.encoded(), "info": "some info"]
49+
}()
50+
51+
let jsonString = try! JSON.Serializer.serialize(json)
52+
//let jsonString = try! json.serialized(options: [.prettyPrint])
53+
54+
try! VDKAParser.parse(jsonString)
55+
56+
//try! JSON.serialize(json)
57+
58+
print("done")

Sources/JSON.swift

+14-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
//
2-
// JSONCore.swift
3-
// JSONCore
4-
//
5-
// Created by Tyrone Trevorrow on 23/10/2015.
6-
// Copyright © 2015 Tyrone Trevorrow. All rights reserved.
7-
//
81

9-
// TODO: Copyright permissions.
2+
3+
// MARK: - VDKA/JSON
104

115
/// Any value that can be expressed in JSON has a representation in `JSON`.
126
public enum JSON {
@@ -22,6 +16,18 @@ public enum JSON {
2216

2317
// MARK: - JSON: CustomStringConvertible
2418

19+
extension JSON {
20+
21+
/**
22+
Turns a nested graph of `JSON`s into a Swift `String`. This produces JSON data that
23+
strictly conforms to [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
24+
It can optionally pretty-print the output for debugging, but this comes with a non-negligible performance cost.
25+
*/
26+
public func serialized(options options: [JSON.Serializer.Option] = []) throws -> String {
27+
return try JSON.Serializer.serialize(self, options: options)
28+
}
29+
}
30+
2531
extension JSON: CustomStringConvertible {
2632
public var description: String {
2733
return (try? self.serialized(options: [.prettyPrint])) ?? "invalid json"

0 commit comments

Comments
 (0)