// Existing test (above) simplified for SO question "Deserialize json array stream one item at a time": // ( http://stackoverflow.com/questions/20374083/deserialize-json-array-stream-one-item-at-a-time ) static void FilteredFatherStreamTestSimplified() { // Get our parser: var parser = new JsonParser(); // (Note this will be invoked thanks to the "filters" dictionary below) Func <object, object> filteredFatherStreamCallback = obj => { Father father = (obj as Father); // Output only the individual fathers that the filters decided to keep (i.e., when obj.Type equals typeof(Father)), // but don't output (even once) the resulting array (i.e., when obj.Type equals typeof(Father[])): if (father != null) { Console.WriteLine("\t\tId : {0}\t\tName : {1}", father.id, father.name); } // Do not project the filtered data in any specific way otherwise, // just return it deserialized as-is: return(obj); }; // Prepare our filter, and thus: // 1) we want only the last five (5) fathers (array index in the resulting "Father[]" >= 29,995), // (assuming we somehow have prior knowledge that the total count is 30,000) // and for each of them, // 2) we're interested in deserializing them with only their "id" and "name" properties var filters = new Dictionary <Type, Func <Type, object, object, int, Func <object, object> > > { // We don't care about anything but these 2 properties: { typeof(Father), // Note the type (type, obj, key, index) => ((key as string) == "id" || (key as string) == "name") ? filteredFatherStreamCallback : JsonParser.Skip }, // We want to pick only the last 5 fathers from the source: { typeof(Father[]), // Note the type (type, obj, key, index) => (index >= 29995) ? filteredFatherStreamCallback : JsonParser.Skip } }; // Read, parse, and deserialize fathers.json.txt in a streamed fashion, // and using the above filters, along with the callback we've set up: using (var reader = new System.IO.StreamReader(FATHERS_TEST_FILE_PATH)) { FathersData data = parser.Parse <FathersData>(reader, filters); System.Diagnostics.Debug.Assert ( (data != null) && (data.fathers != null) && (data.fathers.Length == 5) ); foreach (var i in Enumerable.Range(29995, 5)) { System.Diagnostics.Debug.Assert ( (data.fathers[i - 29995].id == i) && !String.IsNullOrEmpty(data.fathers[i - 29995].name) ); } } Console.ReadKey(); }
// This test deserializes the last ten (10) fathers found in fathers.json.txt, // and performs a fixup of the maiden names (all absent from fathers.json.txt) // of their daughters (if any): static void FilteredFatherStreamTestDaughterMaidenNamesFixup() { Console.Clear(); Console.WriteLine("\"Fathers\" Test... streamed AND filtered"); Console.WriteLine(); Console.WriteLine("(static void FilteredFatherStreamTestDaughterMaidenNamesFixup())"); Console.WriteLine(); Console.WriteLine("(press a key)"); Console.WriteLine(); Console.ReadKey(); // Get our parser: var parser = new JsonParser(); // (Note this will be invoked thanks to the "filters" dictionary below) Func <object, object> filteredFatherStreamCallback = obj => { Father father = (obj as Father); // Processes only the individual fathers that the filters decided to keep // (i.e., iff obj.Type equals typeof(Father)) if (father != null) { if ((father.daughters != null) && (father.daughters.Length > 0)) { // The fixup of the maiden names is done in-place, on // by-then freshly deserialized father's daughters: foreach (var daughter in father.daughters) { daughter.maidenName = father.name.Substring(father.name.IndexOf(' ') + 1); } } } // Do not project the filtered data in any specific way otherwise, // just return it deserialized as-is: return(obj); }; // Prepare our filters, i.e., we want only the last ten (10) fathers // (array index in the resulting "Father[]" >= 29990) var filters = new Dictionary <Type, Func <Type, object, object, int, Func <object, object> > > { // Necessary to perform post-processing on the daughters (if any) // of each father we kept in "Father[]" via the 2nd filter below: { typeof(Father), // Note the type (type, obj, key, index) => filteredFatherStreamCallback }, // We want to pick only the last 10 fathers from the source: { typeof(Father[]), // Note the type (type, obj, key, index) => (index >= 29990) ? filteredFatherStreamCallback : JsonParser.Skip } }; // Read, parse, and deserialize fathers.json.txt in a streamed fashion, // and using the above filters, along with the callback we've set up: using (var reader = new System.IO.StreamReader(FATHERS_TEST_FILE_PATH)) { FathersData data = parser.Parse <FathersData>(reader, filters); System.Diagnostics.Debug.Assert ( (data != null) && (data.fathers != null) && (data.fathers.Length == 10) ); foreach (var father in data.fathers) { Console.WriteLine(); Console.WriteLine("\t\t{0}'s daughters:", father.name); if ((father.daughters != null) && (father.daughters.Length > 0)) { foreach (var daughter in father.daughters) { System.Diagnostics.Debug.Assert ( !String.IsNullOrEmpty(daughter.maidenName) ); Console.WriteLine("\t\t\t\t{0} {1}", daughter.name, daughter.maidenName); } } else { Console.WriteLine("\t\t\t\t(None)"); } } } Console.WriteLine("Press a key..."); Console.ReadKey(); }
static void SpeedTests() { #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().DeserializeObject, OJ_TEST_FILE_PATH, 10000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject, OJ_TEST_FILE_PATH, 10000); //LoopTest("ServiceStack", new JsonSerializer<object>().DeserializeFromString, OJ_TEST_FILE_PATH, 10000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <object>, OJ_TEST_FILE_PATH, 10000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize <HighlyNested>, OJ_TEST_FILE_PATH, 10000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <HighlyNested>, OJ_TEST_FILE_PATH, 10000); LoopTest("ServiceStack", new JsonSerializer <HighlyNested>().DeserializeFromString, OJ_TEST_FILE_PATH, 10000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <HighlyNested>, OJ_TEST_FILE_PATH, 10000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().DeserializeObject, OJ_TEST_FILE_PATH, 100000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject, OJ_TEST_FILE_PATH, 100000); //LoopTest("ServiceStack", new JsonSerializer<object>().DeserializeFromString, OJ_TEST_FILE_PATH, 100000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <object>, OJ_TEST_FILE_PATH, 100000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize <HighlyNested>, OJ_TEST_FILE_PATH, 100000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <HighlyNested>, OJ_TEST_FILE_PATH, 100000); LoopTest("ServiceStack", new JsonSerializer <HighlyNested>().DeserializeFromString, OJ_TEST_FILE_PATH, 100000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <HighlyNested>, OJ_TEST_FILE_PATH, 100000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize <BoonSmall>, BOON_SMALL_TEST_FILE_PATH, 1000000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <BoonSmall>, BOON_SMALL_TEST_FILE_PATH, 1000000); LoopTest("ServiceStack", new JsonSerializer <BoonSmall>().DeserializeFromString, BOON_SMALL_TEST_FILE_PATH, 1000000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <BoonSmall>, BOON_SMALL_TEST_FILE_PATH, 1000000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize <BoonSmall>, BOON_SMALL_TEST_FILE_PATH, 10000000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <BoonSmall>, BOON_SMALL_TEST_FILE_PATH, 10000000); LoopTest("ServiceStack", new JsonSerializer <BoonSmall>().DeserializeFromString, BOON_SMALL_TEST_FILE_PATH, 10000000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <BoonSmall>, BOON_SMALL_TEST_FILE_PATH, 10000000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize <Person>, TINY_TEST_FILE_PATH, 10000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <Person>, TINY_TEST_FILE_PATH, 10000); LoopTest("ServiceStack", new JsonSerializer <Person>().DeserializeFromString, TINY_TEST_FILE_PATH, 10000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <Person>, TINY_TEST_FILE_PATH, 10000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize <Person>, TINY_TEST_FILE_PATH, 100000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <Person>, TINY_TEST_FILE_PATH, 100000); LoopTest("ServiceStack", new JsonSerializer <Person>().DeserializeFromString, TINY_TEST_FILE_PATH, 100000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <Person>, TINY_TEST_FILE_PATH, 100000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize <Person>, TINY_TEST_FILE_PATH, 1000000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <Person>, TINY_TEST_FILE_PATH, 1000000); LoopTest("ServiceStack", new JsonSerializer <Person>().DeserializeFromString, TINY_TEST_FILE_PATH, 1000000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <Person>, TINY_TEST_FILE_PATH, 1000000); #if !JSON_PARSER_ONLY //LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize<DictionaryDataAdaptJsonNetServiceStack>, DICOS_TEST_FILE_PATH, 10000);//(Can't deserialize properly) LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <DictionaryDataAdaptJsonNetServiceStack>, DICOS_TEST_FILE_PATH, 10000); LoopTest("ServiceStack", new JsonSerializer <DictionaryDataAdaptJsonNetServiceStack>().DeserializeFromString, DICOS_TEST_FILE_PATH, 10000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <DictionaryData>, DICOS_TEST_FILE_PATH, 10000); #if !JSON_PARSER_ONLY //LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize<DictionaryDataAdaptJsonNetServiceStack>, DICOS_TEST_FILE_PATH, 100000);//(Can't deserialize properly) LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <DictionaryDataAdaptJsonNetServiceStack>, DICOS_TEST_FILE_PATH, 100000); LoopTest("ServiceStack", new JsonSerializer <DictionaryDataAdaptJsonNetServiceStack>().DeserializeFromString, DICOS_TEST_FILE_PATH, 100000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <DictionaryData>, DICOS_TEST_FILE_PATH, 100000); #if !JSON_PARSER_ONLY //LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize<DictionaryDataAdaptJsonNetServiceStack>, DICOS_TEST_FILE_PATH, 1000000);//(Can't deserialize properly) LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <DictionaryDataAdaptJsonNetServiceStack>, DICOS_TEST_FILE_PATH, 1000000); LoopTest("ServiceStack", new JsonSerializer <DictionaryDataAdaptJsonNetServiceStack>().DeserializeFromString, DICOS_TEST_FILE_PATH, 1000000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <DictionaryData>, DICOS_TEST_FILE_PATH, 1000000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().DeserializeObject, SMALL_TEST_FILE_PATH, 10000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject, SMALL_TEST_FILE_PATH, 10000); //LoopTest("ServiceStack", new JsonSerializer<object>().DeserializeFromString, SMALL_TEST_FILE_PATH, 10000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <object>, SMALL_TEST_FILE_PATH, 10000); #if !JSON_PARSER_ONLY LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().DeserializeObject, SMALL_TEST_FILE_PATH, 100000); LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject, SMALL_TEST_FILE_PATH, 100000);//(JSON.NET: OutOfMemoryException) //LoopTest("ServiceStack", new JsonSerializer<object>().DeserializeFromString, SMALL_TEST_FILE_PATH, 100000); #endif LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse <object>, SMALL_TEST_FILE_PATH, 100000); #if !JSON_PARSER_ONLY var msJss = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue }; Test(typeof(JavaScriptSerializer).FullName, msJss.Deserialize <FathersData>, FATHERS_TEST_FILE_PATH); Test("JSON.NET 5.0 r8", JsonConvert.DeserializeObject <FathersData>, FATHERS_TEST_FILE_PATH); Test("ServiceStack", new JsonSerializer <FathersData>().DeserializeFromString, FATHERS_TEST_FILE_PATH); #endif Test(typeof(JsonParser).FullName, new JsonParser().Parse <FathersData>, FATHERS_TEST_FILE_PATH); if (File.Exists(HUGE_TEST_FILE_PATH)) { #if !JSON_PARSER_ONLY Test(typeof(JavaScriptSerializer).FullName, msJss.DeserializeObject, HUGE_TEST_FILE_PATH); Test("JSON.NET 5.0 r8", JsonConvert.DeserializeObject, HUGE_TEST_FILE_PATH);//(JSON.NET: OutOfMemoryException) //Test("ServiceStack", new JsonSerializer<object>().DeserializeFromString, HUGE_TEST_FILE_PATH); #endif Test(typeof(JsonParser).FullName, new JsonParser().Parse <object>, HUGE_TEST_FILE_PATH); } StreamTest(null); // Note this will be invoked thru the filters dictionary passed to this 2nd "StreamTest" below, in order to: // 1) for each "Father", skip the parsing of the properties to be ignored (i.e., all but "id" and "name") // 2) while populating the resulting "Father[]" array, skip the deserialization of the first 29,995 fathers Func <object, object> mapperCallback = obj => { Father father = (obj as Father); // Output only the individual fathers that the filters decided to keep // (i.e., when obj.Type equals typeof(Father)), // but don't output (even once) the resulting array // (i.e., when obj.Type equals typeof(Father[])): if (father != null) { Console.WriteLine("\t\tId : {0}\t\tName : {1}", father.id, father.name); } // Do not project the filtered data in any specific way otherwise, just return it deserialized as-is: return(obj); }; StreamTest ( new Dictionary <Type, Func <Type, object, object, int, Func <object, object> > > { // We don't care about anything but these 2 properties: { typeof(Father), (type, obj, key, index) => ((key as string) == "id" || (key as string) == "name") ? mapperCallback : JsonParser.Skip }, // We want to pick only the last 5 fathers from the source: { typeof(Father[]), (type, obj, key, index) => (index >= 29995) ? mapperCallback : JsonParser.Skip } } ); FilteredFatherStreamTestDaughterMaidenNamesFixup(); }