Руководство по программированию JSON десериализации в объект C # - PullRequest
0 голосов
/ 07 июня 2018

У нас очень большой плоский объект C # (20000ish свойства), и мы десериализовываем в него объект JSON с помощью десериализатора JSON Newtonsoft.

В настоящее время он занимает более 3 минут из-за отражения.

Мы стремимся внедрить программный процесс десериализации для сокращения этого времени.

Мы прочитали много ресурсов по этому вопросу, они дают общее представление о том, как выполнять десериализацию вручную.но не объясняйте, как подойти к нему программно.

например

http://www.tomdupont.net/2016/01/how-to-optimize-jsonnet-serialization.html

Как повысить скорость десериализации JSON в .Net?(JSON.net или другой?)

Например, у нас есть один крупный объект покупки с 20000 свойствами и без подклассов / свойств объекта, буквально 20000+ строк.То, как они в настоящее время отображаются из JSON, заключается в том, что у нас есть свойство JSON для самого свойства, которое соответствует свойству самого JSON.

Отражение очень медленное с использованием этого текущего подхода, и мы ищем толчокв правильном направлении, как это сделать программно.

1 Ответ

0 голосов
/ 07 июня 2018

Я не уверен, что вы просите.Похоже, вы хотите использовать подход JsonReader / JsonWriter, но не хотите вручную писать 20 000 назначений JSON-свойств (например, if (token.Value == "prop1") result.prop1 = token.Value).Если это так, то вы можете сгенерировать исходный код, который делает то, что вы хотите, и включить результат в свой проект.Есть много способов сделать это.Вот один из способов:

using System;
using System.IO;
using System.Linq;
using System.Text;

namespace GetCustomAttribute
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var sb = new StringBuilder();

            sb.AppendLine(@"
namespace GetCustomAttribute
{
    public static class PurchaseaOrderParser
    {
        public static void Parse(string jsonString, PurchaseOrder purchaseOrder)
        {

            var reader = new JsonTextReader(new StringReader(jsonString));

            var currentProperty = string.Empty;

            while (reader.Read())
            {
                if (reader.Value != null)
                {
                    if (reader.TokenType == JsonToken.PropertyName)
                        currentProperty = reader.Value.ToString();");

            var props = typeof(PurchaseOrder).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(IdAttribute)));
            foreach (var prop in typeof(PurchaseOrder).GetProperties())
            {
                var attribute = prop.GetCustomAttributes(typeof(IdAttribute), false).SingleOrDefault() as IdAttribute;
                if (attribute != null)
                {
                    var s = $"if (reader.TokenType == JsonToken.String && currentProperty == \"{attribute.Id}\") purchaseOrder.{prop.Name} = reader.Value.ToString();";
                    sb.AppendLine(s);
                }
            }

            sb.Append("}}}}}}");

            File.WriteAllText("PurchaseOrderParser.cs", sb.ToString());
        }
    }

    class PurchaseOrder
    {
        [Id("id")]
        public string Id { get; set; }

        [Id("name")]
        public string Name { get; set; }
    }

    class IdAttribute : Attribute
    {
        public string Id { get; set; }

        public IdAttribute(string id) => Id = id;
    }
}

, который выдает:

namespace GetCustomAttribute
{
    public static class PurchaseaOrderParser
    {
        public static void Parse(string jsonString, PurchaseOrder purchaseOrder)
        {

            var reader = new JsonTextReader(new StringReader(jsonString));

            var currentProperty = string.Empty;

            while (reader.Read())
            {
                if (reader.Value != null)
                {
                    if (reader.TokenType == JsonToken.PropertyName)
                        currentProperty = reader.Value.ToString();
if (reader.TokenType == JsonToken.String && currentProperty == "id") purchaseOrder.Id = reader.Value.ToString();
if (reader.TokenType == JsonToken.String && currentProperty == "name") purchaseOrder.Name = reader.Value.ToString();
}}}}}}

.NET также включает возможности генерации кода во время выполнения.Я не знаком с ними, но вы могли бы сделать вышеупомянутое во время выполнения, что бы гарантировать, что синтаксический анализатор не синхронизируется с классом PurchaseOrder.

...