ArduinoJson vs Arduino_JSON
19 November 2019
I recently discovered that the Arduino organization has an “official” JSON library. I usually don’t care about other Arduino JSON libraries, but this one is “official,” so I thought I better take a look.
How ArduinoJson and Arduino_JSON differ?
The “official” library is called Arduino_JSON. I wondered how it compares with ArduinoJson, so I friendly asked the question:
I’m the developer of ArduinoJson. I’m curious to know how this library differs from it. Why should someone choose this one over ArduinoJson?
I received a quite cold (one might say passive-aggressive) answer:
The goal of this library is to be simple to use, and avoid C/C++ concepts that Arduino users are not familiar with.
The person immediately closed the issue, figuratively slamming the door to my face.
From his answer, the author suggests that ArduinoJson is hard to use (really?) and full of obscure C++ notions. I don’t think it’s fair, and thousands of users of the library can testify that it’s not hard to use.
ArduinoJson uses C++ templates, but, as far as the user is concerned, it’s only to specify the size of a StaticJsonDocument
, or to cast a value explicitly. You absolutely can use ArduinoJson without templates.
Disappointed with this answer, I decided to do the comparison myself. This article shows the differences between ArduinoJson 6.13 and the “official” Arduino_JSON 0.1.0 (the latest version).
Features
JSON support | ArduinoJson | Arduino_JSON |
---|---|---|
JSON serialization | ✔️ | ✔️ |
JSON deserialization | ✔️ | ✔️ |
Decode UTF-16 literals | ✔️1 | ✔️ |
Comments in JSON input | ✔️ | |
Single quotes in JSON input | ✔️ | |
Prettified output | ✔️ | |
Deserialization error information | ✔️ | |
Compatible types | ArduinoJson | Arduino_JSON |
Arduino String |
✔️ | ✔️ |
Flash strings | ✔️ | ✔️2 |
Arduino streams | ✔️ | |
STL string | ✔️ | |
STL streams | ✔️ | |
Custom streams | ✔️ | |
long long |
✔️ | |
Integration with the C++ language | ArduinoJson | Arduino_JSON |
Access values with [] |
✔️ | ✔️ |
Implicit casts | ✔️ | ✔️ |
Namespace | ✔️ | |
const friendly |
✔️ | |
for friendly |
✔️ | |
template friendly |
✔️ | |
Usable outside of Arduino | ✔️ | |
Other features | ArduinoJson | Arduino_JSON |
Thread-safe | ✔️ | ✔️ |
MessagePack serialization | ✔️ | |
MessagePack deserialization | ✔️ | |
Stack-only allocation | ✔️ | |
Fixed heap allocation | ✔️ | |
Zero-copy | ✔️ | |
Project information | ArduinoJson | Arduino_JSON |
License | MIT | LGPL |
Test coverage | 98% | 0% |
Popularity | 4055 | 21 |
Documentation | ✔️ |
String
classPerformance
To compare the performance of ArduinoJson and Arduino_JSON, I used the programs in this repository.
To measure the program size, I looked at the output from the Arduino IDE, and I subtracted the size of the Tare program.
To measure the running times, I used the micros()
function.
To count the heap allocations, I replaced malloc()
and realloc()
with functions that increment a counter before forwarding the call to the original function.
To measure the memory usage and fragmentation, I used MemoryInfo from cpp4arduino.
Because ArduinoJson uses a fixed-size memory pool, the results depend on the size of the memory pool. To make a fair comparison with Arduino_JSON, I decided to use a capacity that matches the document (64 B). As always, I used the ArduinoJson Assistant to compute the right capacity.
I ran the tests on an Arduino UNO with Arduino IDE 1.8.10 and AVR core 1.8.1. I expect the results to be similar on other platforms.
Serialize to Serial |
ArduinoJson | Arduino_JSON |
---|---|---|
Program size | 3.6 KB | 7.9 KB |
Running time | 2.2 ms | 2.3 ms |
Heap allocations | 0 | 20 |
RAM usage | 426 B | 454 B |
Fragmentation | 0 % | 1.5 % |
Serialize to String |
ArduinoJson | Arduino_JSON |
Program size | 5.2 KB | 8.0 KB |
Running time | 2.1 ms * | 1.9 ms |
Heap allocations | 2 | 21 |
RAM usage | 499 B | 534 B |
Fragmentation | 0 % | 6.21 % |
Serialize to char[] |
ArduinoJson | Arduino_JSON |
Program size | 3.8 KB | 8.2 KB |
Running time | 1.7 ms | 1.9 ms |
Heap allocations | 0 | 21 |
RAM usage | 492 B | 522 B |
Fragmentation | 0 % | 0 % |
Deserialize from const char* |
ArduinoJson | Arduino_JSON |
Program size | 4.0 KB | 11 KB |
Running time | 0.8 ms | 0.9 ms |
Heap allocations | 0 | 10 |
RAM usage | 449 B | 540 B |
Fragmentation | 0 % | 0% |
Deserialize from char[] |
ArduinoJson | Arduino_JSON |
Program size | 4.1 KB | 11 KB |
Running time | 0.8 ms | 0.9 ms |
Heap allocations | 0 | 10 |
RAM usage | 488 B | 540 B |
Fragmentation | 0 % | 0% |
Deserialize from Serial |
ArduinoJson | Arduino_JSON |
Program size | 4.2 KB | 11.3 KB |
Running time | 2.9 ms | 1004 ms |
Heap allocations | 0 | 73 |
RAM usage | 387 B | 468 B |
Fragmentation | 0 % | 3.82 % |
*: This was fixed in ArduinoJson 6.14.0
Summary
To summarize:
- ArduinoJson has many more features than Arduino_JSON.
- ArduinoJson is almost twice smaller than Arduino_JSON.
- ArduinoJson is slightly faster than Arduino_JSON.
- ArduinoJson consumes less RAM than Arduino_JSON (provided that the memory pool is adjusted).
- ArduinoJson doesn’t increase memory fragmentation.
- Arduino_JSON is slightly easier to use
Why is Arduino_JSON easier to use than ArduinoJson? First, because you don’t have to worry about the capacity of the JsonDocument
. Secondly, because it only supports strings as source and destination, so you don’t need much documentation.
Because I’m the author of one of the library, this article is necessarily biased, so I invite you to compare by yourself. The two libraries have similar APIs, so it’s easy to switch from one to the other.
Are you an ArduinoJson user? Don’t forget to cast a star ⭐ to support the project!