Reusing JSONDecoder or recreating it on every request?
Asked Answered
M

1

5

In an asynchronous environment is it more efficient to use one JSONDecoder for all request (Might result in delays if multiple threads are waiting for the lock) or it's more efficient to create a new JSONDecoder for every new request?

Apple documentation says that the JSONDecoder class is reusable but they don't elaborate further.

https://developer.apple.com/documentation/foundation/jsondecoder

Monetary answered 20/2, 2019 at 13:28 Comment(0)
T
15

On Apple platforms, JSONDecoder relies on JSONSerialization for its initial parsing, and then creates a fresh __JSONDecoder (internal class) to actually do the decoding. It passes an _Options, which is a struct, so that's copied. So there shouldn't be any interaction at all between the threads as long as you're not changing the options (which is not thread-safe).

So it's probably slightly cheaper to reuse the same decoder, since it avoids allocating and deallocating a class instance, which is usually a win over just retaining and releasing a class instance (and I would expect that to be the case here). But I would expect the difference to be very, very small compared to the much larger cost of JSON decoding.

In fact, if I had a situation where this were actually worth profiling (and you would need to profile it to know if it's faster or not), I'd be asking "why in the world am I decoding this many different JSON messages this quickly?" For this to matter, the JSON probably wouldn't be coming from the network or disk (those are so insanely slow to make one extra class allocation meaningless). It would only matter if you were working JSON that is already in memory in huge numbers of small messages. And in that case, the answer would almost certainly be "stop using JSON for that problem."

But I expect that in almost all cases, this just doesn't matter, and I definitely would not proactively optimize it. Implement whichever is clearer in your code. Then profile the code to see where your bottlenecks are.

Tergal answered 20/2, 2019 at 13:55 Comment(4)
Thank you! In my case it's insignificant, but I was just curious whether this made any differences.Monetary
Well your assumptions are totally true in the iOS development context. This would probably matter for a Server Swift App running on OSX that require to Decode/Encode many many many JSON per seconds from the clients inputs. Ok probably it is not a so common case, but I guess in this case would matter. Do you agree?Cavalierly
@Cavalierly You would need to profile it under those conditions (though macOS is rare for server Swift; it's generally Linux). I would be very concerned about multi-threaded contention on retain/release vs just creating fresh objects, but only testing will tell you; when it doubt, be simple. Then profile. But as an example, Kitura generates a new JSONSerialization for every parse request: github.com/IBM-Swift/Kitura/blob/…Tergal
Nowadays, JSONDecoder uses it's own parsing implementation: github.com/apple/swift-corelibs-foundation/blob/main/Sources/…Deland

© 2022 - 2024 — McMap. All rights reserved.