DEV Community

Neil Colvin
Neil Colvin

Posted on Fully Autonomous

System.Text.Json vs Newtonsoft.Json on a Crestron MC4-R (Mono/net472): measured on the processor

Most published STJ-vs-Newtonsoft benchmarks run on desktop or server .NET 8–10. I needed numbers for the runtime my Crestron Home drivers actually run on, so I measured on the processor itself.

Setup

  • Hardware: Crestron MC4-R (hardware version 2), firmware 2.8000.00057 (built 17 Sep 2025), Crestron Home 4.011.0322
  • Runtime: Mono 6.12.0.107, CLR version 4.0.30319.42000, OS reported as Unix 4.19.35.5149
  • Serialisers: System.Text.Json 10.0.12 and Newtonsoft.Json 13.0.5-beta1. The Newtonsoft version was the driver's existing dependency. It's a prerelease that has since been unlisted on NuGet, and the latest stable is 13.0.4. I haven't rerun against 13.0.4. Both serialisers were merged into the test package as private copies.
  • Payload: a synthetic 409-byte response shaped like a WeatherLink API response, deserialised into the same nullable DTOs, which carry attributes for both serialisers. STJ runs with AllowReadingFromString, and Newtonsoft uses its defaults. Results are checked for correctness.
  • Method: Debug harness build (the serialisers are the precompiled NuGet release binaries). 200 warm-up parses per serialiser, then 4 alternating rounds of 3,000 synchronous deserialisations, with a GC before each round. Time is measured with Stopwatch and allocations with GC.GetAllocatedBytesForCurrentThread.
  • Harness: NUnit fixtures run remotely on the processor through my own test adapter (CrestronHomeNUnit).

Results (MC4-R, 3,000 parses per round)

Round System.Text.Json Newtonsoft 13.0.5-beta1 STJ time saving
0 324.553 ms 440.976 ms 26.40%
1 324.821 ms 442.914 ms 26.66%
2 323.404 ms 440.126 ms 26.52%
3 324.255 ms 441.608 ms 26.57%
Per parse 0.108 ms 0.147 ms 26.5%
Allocated per parse 1,024 B 3,816 B 73.2% fewer

Each serialiser's round times stayed within 0.63% of its mean. A short check on desktop .NET 10 also favoured STJ, but its timings varied too much to quote.

Follow-up: STJ vs the processor's resident Newtonsoft (22 Sep)

A second fixture compared bundled STJ with the Newtonsoft.Json already on the processor. That's standard Newtonsoft 13.0.2 at /simpl/app00/, left out of the merge and checked by identity before timing. As in the first run, both packages were Debug harness builds. They ran one after the other in separate host processes.

Round (3,000 parses) Bundled STJ 10.0.12 Resident Newtonsoft 13.0.2
0 324.699 ms 431.950 ms
1 388.026 ms 430.408 ms
2 326.794 ms 430.696 ms
3 326.157 ms 431.120 ms
Per parse 0.114 ms 0.144 ms
Allocated per parse 1,024 B 3,816 B

STJ was about 21% faster overall. Leaving out the slow round 1, it was about 24% faster. The allocation difference is identical to the first run. The raw results include process memory snapshots, but the two runs started from different managed heaps (about 67 MB and 20 MB). Those figures measure host-process state, not serialiser cost, so don't compare them.

What this does and doesn't show

  • On Mono, STJ allocates about a quarter as much as Newtonsoft and parses about 21–27% faster for this payload.
  • These tests used warmed parsing and one small payload shape. They don't cover cold start, serialisation, peak memory or whole-driver CPU.
  • At weather-polling intervals the absolute CPU savings are small. The allocation reduction matters more on a processor shared with other drivers.

Deployment note for Crestron developers

On this firmware, both standard Newtonsoft.Json 13.0.2 and Newtonsoft.Json.Compact 4.0.8.0 are resident in /simpl/app00/, and System.Text.Json isn't. Crestron's driver best-practices page lists Newtonsoft.Json among the DLLs Home loads, but still advises merging your dependencies to avoid DLL conflicts. So STJ has to ship inside your package, and so should Newtonsoft if you use it. None of this was measured against the Compact assembly. That's one firmware on one processor, not a platform guarantee.

Reproduce it

Fixtures, payload, raw results and processor harnesses


AI disclosure: the benchmark fixtures and processor runs were done by GPT-6 Astra, and this write-up was generated by Claude, under my direction.

Top comments (0)