Skip to content

Commit 150f071

Browse files
committed
Improve performance on Linux by using String concatenation and only converting to a Data once
1 parent 37b6641 commit 150f071

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

Foundation/NSJSONSerialization.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,13 @@ open class JSONSerialization : NSObject {
101101
/* Generate JSON data from a Foundation object. If the object will not produce valid JSON then an exception will be thrown. Setting the NSJSONWritingPrettyPrinted option will generate JSON with whitespace designed to make the output more readable. If that option is not set, the most compact possible JSON will be generated. If an error occurs, the error parameter will be set and the return value will be nil. The resulting data is a encoded in UTF-8.
102102
*/
103103
internal class func _data(withJSONObject value: Any, options opt: WritingOptions, stream: Bool) throws -> Data {
104-
var result = Data()
104+
var jsonStr = String()
105105

106106
var writer = JSONWriter(
107107
pretty: opt.contains(.prettyPrinted),
108108
writer: { (str: String?) in
109109
if let str = str {
110-
let count = str.lengthOfBytes(using: .utf8)
111-
result.append(UnsafeRawPointer(str.cString(using: .utf8)!).bindMemory(to: UInt8.self, capacity: count), count: count)
110+
jsonStr.append(str)
112111
}
113112
}
114113
)
@@ -131,6 +130,14 @@ open class JSONSerialization : NSObject {
131130
}
132131
}
133132

133+
let count = jsonStr.lengthOfBytes(using: .utf8)
134+
let bufferLength = count+1 // Allow space for null terminator
135+
var utf8: [CChar] = Array<CChar>(repeating: 0, count: bufferLength)
136+
if !jsonStr.getCString(&utf8, maxLength: bufferLength, encoding: .utf8) {
137+
fatalError("Failed to generate a CString from a String")
138+
}
139+
let rawBytes = UnsafeRawPointer(UnsafePointer(utf8))
140+
let result = Data(bytes: rawBytes.bindMemory(to: UInt8.self, capacity: count), count: count)
134141
return result
135142
}
136143
open class func data(withJSONObject value: Any, options opt: WritingOptions = []) throws -> Data {

0 commit comments

Comments
 (0)