使用 JSchema 进行模式验证的时间问题

Timing issue on schema validation with JSchema

我想使用架构验证 JArray 中的 json 个对象。我的测试数组包含 >100000 个对象。在时序分析过程中,我发现与数组中的第一个对象相比,验证最后一个对象的时间要长很多倍 (>500x)。

这里是我的部分测试代码:

      ...
      string schemaShapeObjectStr = @"{ 'type':'object',
                              '$schema': 'http://json-schema.org/draft-03/schema',
                              'required':false, 
                                  'properties':{ 
                                      'MyShapeObject': { 
                                          'type':'object', 'id': 'MyShapeObject', 'required':true, 
                                          'properties':{ 
                                              'id': {'type':'string', 'id': 'id', 'maxLength': 6,'required':true},
                                              'XY': {'type': 'array','minItems': 2,'maxItems': 2,'uniqueItems': false,'required':true,
                                                  'items': {'type': 'number','multipleOf': 0.001,'minimum': -10000,'maximum': 10000},
                                                  'additionalItems': false
                                              }
                                          }, 'additionalProperties':false 
                                      } 
                                  } 
                              }";
      ...

      JSchema schemaMoveOverTo = JSchema.Parse(schemaMoveOverToStr);

      JArray shapeArray = (JArray)shapes["shape"];

      Int32 counter = 0;

      JObject itemFast = (JObject)shapeArray.First();
      JObject itemSlow = (JObject)shapeArray.Last();

      sw1.Reset();
      sw1.Start();

      foreach (JObject item in shapeArray.Children<JObject>())
      {
          if (item.Properties().First().Name == "MyShapeObject")
          {
              counter++;
              stopwatch2.Reset();
              stopwatch2.Start();
              valid = itemFast.IsValid(schemaShapeObject, out messages);
              stopwatch2.Stop();
              calcTimeFast += stopwatch2.Elapsed;

              stopwatch2.Reset();
              stopwatch2.Start();
              valid = itemSlow.IsValid(schemaShapeObject, out messages);
              stopwatch2.Stop();
              calcTimeSlow += stopwatch2.Elapsed;
          }
      }
      sw1.Stop();
      meassureString = string.Format("loopThru Time = {0}, ShapeObject = {1}", sw1.Elapsed, counter);
      OutPutWindow.AppendText(meassureString + Environment.NewLine);
      meassureString = string.Format("Fast Time = {0}, Fast Mean = {1}, Slow Time = {2}, Slow Mean = {3}", calcTimeFast.TotalMilliseconds, (calcTimeFast.TotalMilliseconds / counter), calcTimeSlow.TotalMilliseconds, (calcTimeSlow.TotalMilliseconds / counter));
      OutPutWindow.AppendText(meassureString + Environment.NewLine);
    ...

我得到了这个输出:

loopThru Time = 00:06:36.1059322, ShapeObject = 89857
Fast Time = 628.6673, Fast Mean = 0.0069963085, Slow Time = 394959.2331, Slow Mean = 4.3954197569

对于我的测试,第一个和最后一个对象是相等的!

在另一个测试中我发现,模式验证时间随着数组中的位置连续增加...

任何人都可以向我解释这种奇怪的行为。老实说,我是一名 C++ 开发人员,并且是 C# 的新手。在我看来,两个 JObject (itemFast, itemSlow) 是相等的并且独立于它们来自哪里!?

我的代码有问题吗?

为什么要循环 shapeArray.Children<JObject>() 的结果然后再不使用它?

itemFast 和 itemSlow 相同吗JSON?这或许可以解释差异。如果没有,请在某处上传一个带有回购协议的控制台项目,我会看看它。