Newtonsoft.Json.JsonConvert.DeserializeObject首次转换太慢问题

不论是.net还是xamarin工程里面转换json一直使用的都是Newtonsoft包,一直也没觉得有什么问题

直到最近安卓设备出现了很奇怪的事情,有个方法居然花费了1秒多,定位后发现是Newtonsoft.Json.JsonConvert.DeserializeObject花了1秒多,这我就傻眼了,这玩意怎么处理,要是都这样,之前的工程不可能没发现啊。

于是用.net弄了个单元测试,居然也要120多毫秒,这也太慢了吧。

 定义类

        public class testjson
        {
            public string aa { get; set; }
            public string bb { get; set; }
            public string cc { get; set; }
        }

测试:

            string output = "{ \"aa\":\"1\",\"bb\":\"哈哈哈哈\",\"cc\":\"和hi黑欸\"} ";
            DateTime start = DateTime.Now;
            testjson res = new testjson();
            object a = Newtonsoft.Json.JsonConvert.DeserializeObject(output, typeof(testjson));
            DateTime end = DateTime.Now;
            TimeSpan bbbb = end - start;
            Console.WriteLine("第一次转换一次花费时间:" + bbbb.TotalMilliseconds);

去网上找了找,看到一些json转换的插件对比测试,Newtonsoft没有这么差啊。做个循环测试,跑个10000次,结果只要26毫秒。

            DateTime start1 = DateTime.Now;
            for (int i = 0; i < 10000; i++)
            {
                string output1 = "{ \"aa\":\"1\",\"bb\":\"哈哈哈哈\",\"cc\":\"和hi黑欸\"} ";
                testjson res1 = new testjson();
                res1 = (testjson)Newtonsoft.Json.JsonConvert.DeserializeObject(output1, typeof(testjson));
            }
            DateTime end1 = DateTime.Now;
            TimeSpan bbbb1 = end1 - start1;
            Console.WriteLine("第二次转换10000次花费时间:" + bbbb1.TotalMilliseconds);

进一步测试,换了个类来转换,同样10000次,只要23毫秒。

换到垃圾安卓板上去测试, 第一次转换1.7秒,接着循环10000次620毫秒。

所以基本可以确定,首次调用  Newtonsoft.Json.JsonConvert.DeserializeObject的时候,会比较慢。

如果没有单独调用第一次,直接循环10000次,就算花费145毫秒,估计也不会发现其中第一次耗费了120秒。

我的想法是,工程启动的时候,随便写个转换先调用下,把第一次的事情做掉,使实际的业务转换受到影响(即使只有第一次)下降到最低。

更多测试,反序列化的和序列化的对比。

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
      [TestMethod]
        public void TestMethod1()
        {
            int counts = 10000;
            DateTime t1 = DateTime.Now;
            DateTime t2 = DateTime.Now;

            string output = "{ \"aa\":\"1\",\"bb\":\"哈哈哈哈\",\"cc\":\"\"} ";
            t1 = DateTime.Now;

            testjson res = (testjson)Newtonsoft.Json.JsonConvert.DeserializeObject(output, typeof(testjson));
            t2 = DateTime.Now;

            Console.WriteLine($"第1次反序列化花费时间:{(t2 - t1).TotalMilliseconds}");

            //string output = "{ \"flag\":\"1\",\"cause\":\"\",\"data\":{ \"aac004\":\"1\",\"ake007\":\"20200226\",\"aac003\":\"黄方金\",\"fplist\":[{\"bkc011\":\"0\",\"bkc010\":\"0\",\"aae072\":\"YD027088915\",\"aka063_mc\":\"诊察费\",\"akc227\":\"17\",\"aaa027\":\"350200\",\"aka063\":\"06\",\"bkc008\":\"17\",\"bkc009\":\"0\"},{\"bkc011\":\".2\",\"bkc010\":\"0\",\"aae072\":\"YD027088915\",\"aka063_mc\":\"检查费\",\"akc227\":\"137.2\",\"aaa027\":\"350200\",\"aka063\":\"08\",\"bkc008\":\"111\",\"bkc009\":\"26\"}],\"mzlist\":[{\"bka542_mc\":\"其中公务员医疗补助\",\"bka542\":\"bkc059_1\",\"bkeb34\":\"0.0\"}],\"akc227\":\"154.2\",\"bkc014\":\"20200226\",\"bke174_mc\":\"省内异地\",\"aac999\":\"350426198801111010\",\"bkc171\":\"1002\",\"aaz149\":\"000000000000\",\"akc190\":\"YD024926537\",\"bkc075\":\"0\",\"amc028\":\"0\",\"bkc059\":\"0\",\"ake026\":\"0\",\"aab004\":\"厦门翼号网络服务有限公司\",\"amc020\":\"0\",\"aka150\":\"4\",\"bke174\":\"1\",\"bkc052\":\"0\",\"aac002\":\"350426198801111010\",\"bae029\":\"1002\",\"bmc041\":\"0\",\"bkc591\":\"0\",\"aaz500\":\"D74781764\",\"bkc102\":\"0\",\"aae072\":\"YD027088915\",\"aae011\":\"lh_hsj\",\"bkc041\":\"154.2\",\"akc087\":\"0\",\"bkc040\":\"0\",\"bkc045\":\"0\",\"bkc062\":\"0\",\"ake173\":\"0\",\"bkc060\":\"0\"},\"traceid\":\"\"}";
            t1 = DateTime.Now;
            testjson item = new testjson()
            {
                aa = "aljfdlsjflkjsdlf",
                bb = "sdfsdfsdfds啊哈哈的撒发",
                cc = "af;djaf;lkdsjf"
            };



            string mmm = Newtonsoft.Json.JsonConvert.SerializeObject(item);
            t2 = DateTime.Now;
            Console.WriteLine("第1次序列化花费时间:" + (t2 - t1).TotalMilliseconds);

            t1 = DateTime.Now;
            for (int i = 0; i < counts; i++)
            {
                string output1 = "{ \"aa\":\"1\",\"bb\":\"哈哈哈哈\",\"cc\":\"和hi黑欸\"} ";
                testjson res1 = new testjson();
                res1 = (testjson)Newtonsoft.Json.JsonConvert.DeserializeObject(output1, typeof(testjson));
            }
            t2 = DateTime.Now;

            Console.WriteLine($"第2次反序列化{counts}次花费时间:{(t2 - t1).TotalMilliseconds}");


            t1 = DateTime.Now;
            for (int i = 0; i < counts; i++)
            {
                string nnnnn = Newtonsoft.Json.JsonConvert.SerializeObject(item);
            }
            t2 = DateTime.Now;

            Console.WriteLine($"第2次序列化{counts}次花费时间:{(t2 - t1).TotalMilliseconds}");

            t1 = DateTime.Now;
            for (int i = 0; i < counts; i++)
            {
                if (i % 2 == 1)
                {
                    string output2 = "{ \"aaaa\":\"1\",\"bbb\":\"哈哈哈哈\",\"ccc\":\"和hi黑欸\"} ";
                    testjson2 res2 = new testjson2();
                    res2 = (testjson2)Newtonsoft.Json.JsonConvert.DeserializeObject(output2, typeof(testjson2));
                }
                else
                {
                    string output1 = "{ \"aa\":\"1\",\"bb\":\"哈哈哈哈\",\"cc\":\"和hi黑欸\"} ";
                    testjson res1 = new testjson();
                    res1 = (testjson)Newtonsoft.Json.JsonConvert.DeserializeObject(output1, typeof(testjson));
                }
            }
            t2 = DateTime.Now;

            Console.WriteLine($"第2次反序列化{counts}次(反复切换类),花费时间:{(t2 - t1).TotalMilliseconds}");
         

        }


        public class testjson
        {
            public string aa { get; set; }
            public string bb { get; set; }
            public string cc { get; set; }

        }

        public class testjson2
        {
            public string aaa { get; set; }
            public string bbb { get; set; }
            public string ccc { get; set; }

        }
    }
}

测试结果:首次反序列化都要120毫秒,首次序列化也要20多毫秒,反过先做序列化也是首次120毫秒左右,首次反序列化20毫秒左右。再后续一万次的时间也只要20毫秒左右,序列化相对来说比反序列化要快一些。

也就是说 jsonconvert "首次"调用的时候可能在100毫秒左右,然后"首次"调用序列化或者反序列化需要20毫秒左右,再往后的调用耗时就几乎可以忽略不计了。

 

目前我的猜想是首次调用做了一些初始化的工作,具体的后续去看下newtonsoftd的源码再分析,待续....

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值