我正在寻找一种性能优化的解决方案,我正试图为一些使用金融市场订单簿的代码找到合适的解决方案,基本上,我要返回的JSON对象有一个数组类型的属性,包含数百/数千个订单对象,但是我只对其中的10到20个对象感兴趣(需要动态确定)。从性能的角度来看,我更愿意跳过反序列化&在添加了所需的项之后添加数组中的每个项。为了澄清,它总是数组中我实际需要的前10到20项,这之后的一切都可以被排除在外。
在Json.NET中有实现这一目标的方法吗?我一直在看JsonConverters,但搞不懂。
发布于 2021-10-11 17:22:35
您可以创建以下JsonConverter<T []>,它将跳过数组条目,超出一定数量:
public class MaxLengthArrayConverter<T> : JsonConverter<T []>
{
public MaxLengthArrayConverter(int maxLength) => this.MaxLength = maxLength >= 0 ? maxLength : throw new ArgumentException(nameof(maxLength));
public int MaxLength { get; }
public override T [] ReadJson(JsonReader reader, Type objectType, T [] existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.MoveToContentAndAssert().TokenType == JsonToken.Null)
return null;
reader.AssertTokenType(JsonToken.StartArray);
var list = new List<T>();
while (reader.ReadToContentAndAssert().TokenType != JsonToken.EndArray)
{
if (list.Count < MaxLength)
list.Add(serializer.Deserialize<T>(reader));
else
reader.Skip();
}
return list.ToArray();
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, T [] value, JsonSerializer serializer) => throw new NotImplementedException();
}
public static partial class JsonExtensions
{
public static JsonReader AssertTokenType(this JsonReader reader, JsonToken tokenType) =>
reader.TokenType == tokenType ? reader : throw new JsonSerializationException(string.Format("Unexpected token {0}, expected {1}", reader.TokenType, tokenType));
public static JsonReader ReadToContentAndAssert(this JsonReader reader) =>
reader.ReadAndAssert().MoveToContentAndAssert();
public static JsonReader MoveToContentAndAssert(this JsonReader reader)
{
if (reader == null)
throw new ArgumentNullException();
if (reader.TokenType == JsonToken.None) // Skip past beginning of stream.
reader.ReadAndAssert();
while (reader.TokenType == JsonToken.Comment) // Skip past comments.
reader.ReadAndAssert();
return reader;
}
public static JsonReader ReadAndAssert(this JsonReader reader)
{
if (reader == null)
throw new ArgumentNullException();
if (!reader.Read())
throw new JsonReaderException("Unexpected end of JSON stream.");
return reader;
}
}然后,假设您的金融市场订单模型如下所示:
public class OrderBook
{
public Order [] Orders { get; set; }
}您可以按以下方式反序列化:
int maxLength = 20; // Or whatever you want.
var settings = new JsonSerializerSettings
{
Converters = { new MaxLengthArrayConverter<Order>(maxLength) },
};
var model = JsonConvert.DeserializeObject<OrderBook>(json, settings);
Assert.IsTrue(model.Orders.Length <= maxLength);备注:
T []的数组截断到特定长度。如果这不是真的,并且在运行时单独指定不同的数组需要不同的最大长度,那么您将需要一个更复杂的解决方案,可能涉及自定义契约解析器。演示小提琴这里。
https://stackoverflow.com/questions/69524417
复制相似问题