Subscript performance in JSONObject
ivan-ushakov opened this issue · 7 comments
I faced with strange performance problem. When I use JSONObject directly with Data object, subscript access takes much more time than parsing.
4.16 s 45.0% 24.00 ms JSONObject.subscript.getter
1.43 s 15.4% 5.00 ms JSONObject.init(data:)
463.00 ms 5.0% 7.00 ms JSONArrayIterator.next()
This is for ~ one million calls to JSONArray(data: ) and some hand transformation of returned object to structure. Looks like parsing is much cheaper than access to object field by name.
Is there anything you can share about the data structure? It is a particularly big array or object, for example?
This is a file with ~ 1 million JSON objects. I read each object to array and pass this array to JSONObject class. After that I work with object properties. Each object looks like this:
[
{"company":"Рога и копыта", "debt": 800, "phones": [123, 234, 456]},
{"company":"Первая коллекторская", "debt": 1200, "phones": [2128506, 456, 789]},
{"company":"Святой престол", "debt": "666", "phones": 666},
{"company": "Казачий спас", "debt": 1500, "phones": [234567, "345678"], "phone": 666},
{"company": {"name": "Шестерочка"}, "debt": 2550, "phones": 788, "phone": 789},
{"company":"Рога и копыта", "debt": 800, "phones": [123, 234, 456]},
{"company":"Первая коллекторская", "debt": 1200, "phones": [2128506, 456, 789]},
{"company":"Святой престол", "debt": "666", "phones": 666},
{"company": "Казачий спас", "debt": 1500, "phones": [234567, "345678"], "phone": 666}
]
As you see phones
attribute could be Array or String, and Array could contain String or Number. This is the reason why I need to use subscript getter and as?
operator.
In my current test it looks like getting object property by name takes more than parsing object.
Thanks! I'll have a stab at this by generating a JSON for myself to test this upon. For clarity, what are the three numbers? 4.16s is the total time spent in that function I assume. And 24ms would be the average execution time of that function?
Yes, you are right.
Short update; Swift is adding a tonne of extra retains and releases in that code. These accumulate to be at least above 60% of the performance cost of a subscript. Thanks for highlighting this for me :)
Technically everything you would need is present in the JSONDescription, but I'm struggling to create a good public API for it. If I could help you utilize the JSONDescription, it would allow you to read/search the JSON DataSet more directly, not using the JSONObject and JSONArray types.
In that case you'd have no overhead from the iterator and subscripts.
If anyone has specific APIs they want for improved parsing performance, create a new issue.