Preamble
Being engaged in writing interface / middleware for a single IPTV-STB set-top box, I ran into a rather slow javascript parser of the built-in Opera when calling eval (while Opera was not built in, but ANT Galio was even sadder, but this is a topic for another conversation). That is, there everything works slowly, because it's still just a prefix, but in this particular case it was necessary to do something with the brakes - the TV program was loaded via ajax, and while eval was parsing the incoming JSON line, the prefix didn’t respond to user actions at all (and long enough) . As a result, I solved the issue using
JSONP , which I earned on the console several times faster (and at the same time I solved the problem with cross-domainness), but in passing I thought about the performance of parsers in principle. On Habré, I found
only one article about it, but JSONP was not there ... Plus, there were some positive criticisms in the comments, so I decided to conduct my own testing. All parsers from
JSON.org and browsers Opera 9.64, Firefox 3.5, Internet Explorer 8, Google Chrome 2, Safari 4 are used.
Testing method
In the comments to the above article, we noticed that browsers can cache the result of parsing, so it’s not quite correct to simply “run” the same line a hundred times to get a reliable result. In addition, there is no parsing as such in JSONP - it’s more likely a parsing of JavaScript as such.
As a result, a short php script was written, which stands on the server and generates, on request, a JSON string containing an array with a specified number of objects in this format:
{
"key_string1" : "qkrlgthcnadzemsiuwvbfopxyj",
"key_string2" : "zbntiyjchfpsraudqxkgomvwle",
"key_int" : 25721,
"key_arr" : [21,25,19,16,10,4,27,17,6,12,22,29,5,1,26,28,23,14,24,13,3,18,30,15,2,11,8,20,9,7],
"key_float" : 2110.1
}
The contents of the properties of objects are filled randomly each time, and the script itself is called with prevention of caching.
For the test itself, a page was written, requesting in different ways a JSON string with a different number of objects in the array from the server and measuring the download and parsing times (in the case of JSONP, all at once). For a more accurate result, all requests were conducted 50 times. The following parsing methods are used:
- JSONP - in the most classic version - the connected script calls a callback with a JSON object as a parameter. The main disadvantage is a low level of security, since In the connected script there can be anything.
- XMLHttpRequest + json2.js is essentially a regular eval, only slightly refined with a few regexps to check the validity of the JSON string code itself. The disadvantage is because eval is used, you can still try to include js-code in the string and “mess up” on the client.
- XMLHttpRequest + json_parse.js - full-fledged JSON parsing. Eval is not used, so everything is in order with safety, and the main drawback is low speed.
- XMLHttpRequest + json_sans_eval - Google's parser. Does not use eval - therefore it is safe, and uses a minimum of code - therefore it is fast. :-) The disadvantage is that it does not validate a JSON string, so if it is “broken” or incorrect, the result is unpredictable. :-) I mean, as a result of the parsing, some crap will be returned.
- XMLHttpRequest + native JSON parsers - I couldn't help but include native JSON parsers that are present in recent versions of IE and FF. :-)
I tested everything on my home computer (Athlon64 X2 5200+, 2GB of memory, Windows XP SP2), and the scripts were run from a server located nearby in the local network (in order to have a little positive effect on transport delays). I want to warn you in advance that these transport delays are nevertheless fully present (around 200 ms), and with a rather large such spread, so you shouldn’t focus on the absolute values ​​of the tests - the relative by eye comparison of different parsers and browsers is much more important . I tried to test on localhost, but php-cgi running shttps is even slower, and creating a special test bench was a bit lazy.
And as for browsers. Official latest official versions of official releases were used, available on browser sites as of 07/02/2009. Therefore, for example, Opera is not the 10th - which, perhaps, many would like. IE6 is not there either - I could have started it only in IETester, but it seems to me that the results from there would not be entirely correct. The test was run in a single tab immediately after the launch of each browser. During its operation, different browsers loaded the processor differently and consumed different amounts of memory, but this is a topic for a separate study.
')
Test results
All results are in tabular form. For all parsers, the first line shows the total execution time in milliseconds (data request + parsing), the second (except for JSONP) shows the time for only parsing. Only the first line makes sense to compare with JSONP, the second one only serves to compare the other parsers among themselves.
Google Chrome 2Parser | Number of objects in an array in a JSON string |
---|
25 | 50 | 100 | 200 | 400 | 800 |
---|
Jsonp | 187 | 187 | 211 | 197 | 213 | 242 |
Json_json2 | 189 | 189 | 193 | 200 | 220 | 253 |
JSON_json2 - parse | 2 | four | 6 | 12 | 21 | 42 |
Json_json_parse | 192 | 194 | 198 | 212 | 241 | 311 |
JSON_json_parse - parse | four | 6 | eleven | 22 | 45 | 92 |
Json_json_sans_eval | 190 | 190 | 191 | 231 | 240 | 259 |
JSON_json_sans_eval - parse | one | 3 | 6 | eleven | 23 | 48 |
Firefox 3.5Parser | Number of objects in an array in a JSON string |
---|
25 | 50 | 100 | 200 | 400 | 800 |
---|
Jsonp | 212 | 215 | 219 | 222 | 233 | 277 |
Json_json2 | 219 | 224 | 224 | 239 | 270 | 384 |
JSON_json2 - parse | 3 | 6 | 12 | 25 | 51 | 106 |
Json_json_parse | 223 | 255 | 276 | 353 | 529 | 820 |
JSON_json_parse - parse | nineteen | 36 | 72 | 145 | 288 | 578 |
Json_json_sans_eval | 219 | 225 | 224 | 257 | 307 | 365 |
JSON_json_sans_eval - parse | five | eight | sixteen | 31 | 62 | 123 |
Json_native | 198 | 211 | 219 | 233 | 244 | 261 |
JSON_native - parse | one | one | 2 | four | 9 | 17 |
Opera 9.64Parser | Number of objects in an array in a JSON string |
---|
25 | 50 | 100 | 200 | 400 | 800 |
---|
Jsonp | 307 | 356 | 371 | 395 | 390 | 430 |
Json_json2 | 323 | 332 | 344 | 391 | 463 | 693 |
JSON_json2 - parse | eight | sixteen | 31 | 67 | 138 | 343 |
Json_json_parse | 316 | 333 | 363 | 438 | 553 | 829 |
JSON_json_parse - parse | eleven | 22 | 54 | 112 | 231 | 476 |
Json_json_sans_eval | 311 | 323 | 352 | 380 | 436 | 588 |
JSON_json_sans_eval - parse | five | 12 | 23 | 53 | 114 | 237 |
Internet Explorer 8Parser | Number of objects in an array in a JSON string |
---|
25 | 50 | 100 | 200 | 400 | 800 |
---|
Jsonp | 191 | 191 | 198 | 201 | 217 | 244 |
Json_json2 | 216 | 204 | 212 | 218 | 251 | 220 |
JSON_json2 - parse | 3 | five | eleven | 22 | 45 | 92 |
Json_json_parse | 238 | 287 | 399 | 523 | 864 | 1672 |
JSON_json_parse - parse | 45 | 90 | 191 | 327 | 643 | 1443 |
Json_json_sans_eval | 203 | 213 | 273 | 306 | 412 | 681 |
JSON_json_sans_eval - parse | 9 | 20 | 54 | 107 | 204 | 448 |
Json_native | 195 | 196 | 209 | 201 | 219 | 250 |
JSON_native - parse | one | one | four | five | eleven | 27 |
Safari 4Parser | Number of objects in an array in a JSON string |
---|
25 | 50 | 100 | 200 | 400 | 800 |
---|
Jsonp | 204 | 228 | 208 | 221 | 238 | 280 |
Json_json2 | 198 | 200 | 202 | 210 | 232 | 266 |
JSON_json2 - parse | one | 2 | four | eight | sixteen | 31 |
Json_json_parse | 224 | 205 | 213 | 239 | 273 | 351 |
JSON_json_parse - parse | four | 7 | 14 | 28 | 56 | 111 |
Json_json_sans_eval | 202 | 205 | 211 | 226 | 260 | 324 |
JSON_json_sans_eval - parse | 3 | five | ten | 20 | 41 | 80 |
UPD :
deerua drew nice graphics for each parser - rejoice:
Jsonp
Json_json2
Json_json_parse
Json_json_sans_eval
Json_native
findings
On the one hand, the results are rather unrepresentative - most differences are concealed by a 200 millisecond delay (and its spread between different launches) when calling the server script, which returns data. On the other hand, a number of conclusions can be made not only, but also necessary:
- JSONP is really fast! Its speed is the same in all browsers (unless Opera let us down), and the scalability is much better than that of any other parsers. The speed of its work depends most of all on the server itself, giving the content - hence the random variation in the results. In any case, if there are no special security requirements on the client, then JSONP is the optimal choice for transmitting and parsing JSON data.
- If we are not talking about large amounts of data (the file for 800 objects from this test takes about 190kb) and the use of IE, the time difference between the other parsers is not very significant. This refers to the total execution time, not just JSON parsing.
- The built-in JSON parsers in FF and IE showed the best results in terms of the speed of parsing. Considering also that they provide complete security, it clearly makes sense to use them.
- The Google parser json_sans_eval is not much slower than json2 running on classic eval, but it provides a high level of security. Therefore, if the resulting JSON object then passes a separate validation in the process of use, then this will obviously be the best compromise.
- From browsers, Chrome and Safari performed best. Given that the legs of both grow from one place - WebKit uniquely taxis. :-)
- Opera and Firefox were extremely mediocre, and IE8 was ambiguous: a great native parser and eval work and at the same time a terrible "manual" line parsing. Obviously, the matter is in the backward js-engine.
So, I hope it was interesting to anyone except me. :-) Maybe later I will improve the test by removing the transport component from it, but for the initial assessment of the speed of the parsers and browsers, and this, in my opinion, is enough ...
ps: But if the hub allowed to set bgcolor in the rows of tables - the results would be much more beautiful ...