using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public static void Test()
var text1 = TestOriginal(json);
Console.WriteLine(text1);
var text2 = TestImproved(json);
Assert.AreEqual(text1, text2);
var text3 = TestDataModel(json);
Assert.AreEqual(text1, text3);
var elapsed1 = Time(() => TestOriginal(json), count);
var elapsed2 = Time(() => TestOriginalWithNoSort(json), count);
var elapsed3 = Time(() => TestImproved(json), count);
var elapsed4 = Time(() => TestDataModel(json), count);
Console.WriteLine("Average time per repetition for {0} reps of original code: {1:0.0000} ms.", count, elapsed1.TotalMilliseconds/((double)count));
Console.WriteLine("Average time per repetition for {0} reps of original code without sorting: {1:0.0000} ms ({2:0.00}% faster).", count, elapsed2.TotalMilliseconds/((double)count), 100.0*(elapsed1 - elapsed2)/elapsed1);
Console.WriteLine("Average time per repetition for {0} reps of modified code: {1:0.0000} ms ({2:0.00}% faster).", count, elapsed3.TotalMilliseconds/((double)count), 100.0*(elapsed1 - elapsed3)/elapsed1);
Console.WriteLine("Average time per repetition for {0} reps of deserialized data model: {1:0.0000} ms ({2:0.00}% faster).", count, elapsed4.TotalMilliseconds/((double)count), 100.0*(elapsed1 - elapsed4)/elapsed1);
static TimeSpan Time(Action action, int count)
var stopwatch = new System.Diagnostics.Stopwatch();
for (int i = 0; i < count; i++)
return stopwatch.Elapsed;
static string TestOriginalWithNoSort(string json)
var root = JToken.Parse(json);
var jsonArray = (JArray)root["results"];
var jsonlBuilder = new StringBuilder();
var serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings { DateTimeZoneHandling = DateTimeZoneHandling.Utc });
using (var textWriter = new StringWriter(jsonlBuilder))
using (var jsonWriter = new JsonTextWriter(textWriter) { Formatting = Formatting.None })
foreach (var obj in jsonArray)
var employments = obj.SelectToken("examples");
if (employments.Count() > 1)
var b = employments.ToObject<JArray>().OrderBy(c => c.SelectToken("date").ToObject<DateTime>(serializer));
var newEmploymentArray = new JArray(b);
obj["examples"].Replace(newEmploymentArray);
jsonWriter.WriteWhitespace("\n");
return jsonlBuilder.ToString();
static string TestOriginal(string json)
var root = JToken.Parse(json);
var jsonArray = (JArray)root["results"];
var jsonlBuilder = new StringBuilder();
var serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings { DateTimeZoneHandling = DateTimeZoneHandling.Utc });
using (var textWriter = new StringWriter(jsonlBuilder))
using (var jsonWriter = new JsonTextWriter(textWriter) { Formatting = Formatting.None })
foreach (var obj in jsonArray)
var employments = obj.SelectToken("examples");
if (employments.Count() > 1)
var b = employments.ToObject<JArray>().OrderBy(c => c.SelectToken("date").ToObject<DateTime>(serializer));
var newEmploymentArray = new JArray(b);
obj["examples"].Replace(newEmploymentArray);
jsonWriter.WriteWhitespace("\n");
return jsonlBuilder.ToString();
static string TestImproved(string json)
var settings = new JsonSerializerSettings {
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
DateParseHandling = DateParseHandling.DateTime
using var textReader = new StringReader(json);
using var jsonReader = new JsonTextReader(textReader);
var root = JsonSerializer.CreateDefault(settings).Deserialize<JToken>(jsonReader);
var jsonArray = (JArray)root["results"];
var jsonlBuilder = new StringBuilder();
using (var textWriter = new StringWriter(jsonlBuilder))
using (var jsonWriter = new JsonTextWriter(textWriter) { Formatting = Formatting.None })
foreach (var obj in jsonArray)
var employments = obj is JObject ? obj["examples"] as JArray : null;
if (employments.Count > 1)
var sortedList = employments
.Select(e => (e, date : e["date"].Value<DateTime>()))
.OrderBy(p => p.date).Select(p => p.e)
foreach (var item in sortedList)
jsonWriter.WriteWhitespace("\n");
return jsonlBuilder.ToString();
public string id { get; set; }
public DateTime date { get; set; }
public object parent_group { get; set; }
public string type { get; set; }
public string id { get; set; }
public List<Group> groups { get; set; } = new ();
public List<Example> examples { get; set; } = new ();
public List<Result> results { get; set; } = new ();
static string TestDataModel(string json)
var settings = new JsonSerializerSettings {
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
var serializer = JsonSerializer.CreateDefault(settings);
using var textReader = new StringReader(json);
using var jsonReader = new JsonTextReader(textReader);
var root = serializer.Deserialize<Root>(jsonReader);
var jsonArray = root.results;
var jsonlBuilder = new StringBuilder();
using (var textWriter = new StringWriter(jsonlBuilder))
using (var jsonWriter = new JsonTextWriter(textWriter) { Formatting = Formatting.None })
foreach (var obj in jsonArray)
if (obj?.examples != null && obj.examples.Count > 0)
obj.examples.Sort((x, y) => x.date.CompareTo(y.date));
serializer.Serialize(jsonWriter, obj);
jsonWriter.WriteWhitespace("\n");
return jsonlBuilder.ToString();
static string GetJson() =>
"id": "e13b1e97-31e3-46e6-9d8f-9776c52e5ce0",
"date": "2020-05-10T00:00:00Z"
"id": "bd31d475-6137-4409-8d17-535f1bf94071",
"date": "2021-05-11T00:00:00Z"
"id": "0e0806ba-56f6-4527-8fd7-7e0061e30783",
"date": "2019-05-11T00:00:00Z"
"id": "e13b1e97-31e3-46e6-9d8f-9776c52e5ce0",
"date": "2020-05-10T00:00:00Z"
"id": "bd31d475-6137-4409-8d17-535f1bf94071",
"date": "2021-05-11T00:00:00Z"
"id": "0e0806ba-56f6-4527-8fd7-7e0061e30783",
"date": "2019-05-11T00:00:00Z"
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("{0} version: {1}", typeof(JsonSerializer).Namespace, typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");