2022-01-23 10:41:00 +00:00
using System.Text ;
using System.Text.Json ;
using BenchmarkDotNet.Attributes ;
using BenchmarkDotNet.Running ;
using Newtonsoft.Json ;
using Newtonsoft.Json.Linq ;
namespace PettingZoo.Benchmark
{
/ *
Small JSON
| Method | Mean | Error | StdDev | Gen 0 | Allocated |
| - - - - - - - - - - - - - - - - - | - - - - - - - - - - : | - - - - - - - - - - : | - - - - - - - - - - : | - - - - - - - : | - - - - - - - - - - : |
| TestJsonConvert | 13.226 us | 0.1808 us | 0.1603 us | 3.6316 | 15 KB |
| TestJTokenParse | 12.360 us | 0.2453 us | 0.5010 us | 3.6011 | 15 KB |
| TestReaderWriter | 6.398 us | 0.1260 us | 0.1294 us | 2.0294 | 8 KB |
| TestJsonDocument | 4.400 us | 0.0758 us | 0.0902 us | 2.1019 | 9 KB |
Large JSON ( 25 MB )
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
| - - - - - - - - - - - - - - - - - | - - - - - - - - - - - : | - - - - - - - - - : | - - - - - - - - - : | - - - - - - - - - - - : | - - - - - - - - - - - : | - - - - - - - - - - : | - - - - - - - - - - : |
| TestJsonConvert | 1 , 331.6 ms | 20.36 ms | 19.05 ms | 57000.0000 | 21000.0000 | 3000.0000 | 390 MB |
| TestJTokenParse | 1 , 411.0 ms | 27.28 ms | 24.18 ms | 62000.0000 | 23000.0000 | 4000.0000 | 415 MB |
| TestReaderWriter | 298.6 ms | 5.89 ms | 9.34 ms | 25000.0000 | 8000.0000 | 2000.0000 | 199 MB |
| TestJsonDocument | 278.5 ms | 5.29 ms | 6.30 ms | - | - | - | 246 MB |
* /
[MemoryDiagnoser]
public class JsonPrettyPrint
{
// Small Json file, which is likely to be typical for most RabbitMQ messages.
private const string Json = "{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\",\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup Language\",\"Acronym\":\"SGML\",\"Abbrev\":\"ISO 8879:1986\",\"GlossDef\":{\"para\":\"A meta-markup language, used to create markup languages such as DocBook.\",\"GlossSeeAlso\":[\"GML\",\"XML\"]},\"GlossSee\":\"markup\"}}}}}" ;
// To test with a large file instead, specify the file name here.
// For example, I've benchmarked it with this 25 MB JSON file: https://raw.githubusercontent.com/json-iterator/test-data/master/large-file.json
//private const string JsonFilename = "";
private const string JsonFilename = "D:\\Temp\\large-file.json" ;
private readonly string testJson ;
public JsonPrettyPrint ( )
{
testJson = string . IsNullOrEmpty ( JsonFilename )
? Json
: File . ReadAllText ( JsonFilename ) ;
}
[Benchmark]
public string TestJsonConvert ( )
{
var obj = JsonConvert . DeserializeObject ( testJson ) ;
return JsonConvert . SerializeObject ( obj , Formatting . Indented ) ;
}
[Benchmark]
public string TestJTokenParse ( )
{
var obj = JToken . Parse ( testJson ) ;
return obj . ToString ( Formatting . Indented ) ;
}
[Benchmark]
2022-01-23 10:41:57 +00:00
public string TestReaderWriter ( )
2022-01-23 10:41:00 +00:00
{
using var stringReader = new StringReader ( testJson ) ;
using var jsonTextReader = new JsonTextReader ( stringReader ) ;
using var stringWriter = new StringWriter ( ) ;
using var jsonWriter = new JsonTextWriter ( stringWriter ) ;
jsonWriter . Formatting = Formatting . Indented ;
while ( jsonTextReader . Read ( ) )
jsonWriter . WriteToken ( jsonTextReader ) ;
jsonWriter . Flush ( ) ;
return stringWriter . ToString ( ) ;
}
[Benchmark]
public string TestJsonDocument ( )
{
var doc = JsonDocument . Parse ( testJson ) ;
using var stream = new MemoryStream ( ) ;
var writer = new Utf8JsonWriter ( stream , new JsonWriterOptions { Indented = true } ) ;
doc . WriteTo ( writer ) ;
writer . Flush ( ) ;
return Encoding . UTF8 . GetString ( stream . ToArray ( ) ) ;
}
}
public class Program
{
public static void Main ( )
{
BenchmarkRunner . Run < JsonPrettyPrint > ( ) ;
// To prove they all provide the correct output
/ *
var prettyPrint = new JsonPrettyPrint ( ) ;
Console . WriteLine ( "JsonConvert" ) ;
Console . WriteLine ( "-----------" ) ;
Console . WriteLine ( prettyPrint . TestJsonConvert ( ) ) ;
Console . WriteLine ( "JToken" ) ;
Console . WriteLine ( "------" ) ;
Console . WriteLine ( prettyPrint . TestJTokenParse ( ) ) ;
Console . WriteLine ( "ReaderWriter" ) ;
Console . WriteLine ( "------------" ) ;
Console . WriteLine ( prettyPrint . TestReaderWriter ( ) ) ;
Console . WriteLine ( "JsonDocument" ) ;
Console . WriteLine ( "------------" ) ;
Console . WriteLine ( prettyPrint . TestJsonDocument ( ) ) ;
* /
}
}
}