Skip to content

[perf] JSON encoding can be faster by skipping string building. #2393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 17, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions Foundation/JSONSerialization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,14 @@ open class JSONSerialization : NSObject {
/* 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.
*/
internal class func _data(withJSONObject value: Any, options opt: WritingOptions, stream: Bool) throws -> Data {
var jsonStr = String()
var jsonStr = [UInt8]()

var writer = JSONWriter(
pretty: opt.contains(.prettyPrinted),
sortedKeys: opt.contains(.sortedKeys),
writer: { (str: String?) in
if let str = str {
jsonStr.append(str)
jsonStr.append(contentsOf: Array(str.utf8))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this when I scanned this earlier but you could be able to avoid the array allocation by just doing jsonStr.append(contentsOf: str.utf8) right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it seems it should work. I will prepare a follow up. Thanks for pointing it out!

}
}
)
Expand All @@ -147,10 +147,8 @@ open class JSONSerialization : NSObject {
fatalError("Top-level object was not NSArray or NSDictionary") // This is a fatal error in objective-c too (it is an NSInvalidArgumentException)
}

let count = jsonStr.utf8.count
return jsonStr.withCString {
Data(bytes: $0, count: count)
}
let count = jsonStr.count
return Data(bytes: &jsonStr, count: count)
}

open class func data(withJSONObject value: Any, options opt: WritingOptions = []) throws -> Data {
Expand Down