1. 程式人生 > >Asp.net Web Api開發(第二篇)效能:使用Jil提升Json序列化效能

Asp.net Web Api開發(第二篇)效能:使用Jil提升Json序列化效能

看了幾篇網上關於各種序列化工具的效能對比,在這裡再貼上下:


我們使用了ASP.NET WEB API來提供RESTfull風格的介面給APP呼叫,預設序列化庫用的是:Newtonsoft.Json

為了進一步提高服務端的效能,有必要將序列化庫進行替換。從上圖可以看出,Jil是最快的Json序列化庫了。為了驗證其效能,我們也寫了相關程式碼,將Jil和Newtonsoft.Json進行的比較。確實Jil的效能要優越不少。於是決定就用Jil來替換了。

第一步:引用Jil.dll,同目錄下也要有Sigil.dll,Jil是基於Sigil開發的。

第二部:編寫一個JilFormatter:

using Jil;
using System;
using System.IO;
using System.Net;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace RRPService.WebApi.Comm
{
    public class JilFormatter: MediaTypeFormatter
    {
        private readonly Options mJilOptions;

        /// <summary>
        /// Jil Json序列化器
        /// </summary>
        public JilFormatter()
        {
            mJilOptions = new Options(
                dateFormat: DateTimeFormat.MillisecondsSinceUnixEpoch,
                excludeNulls:true,
                includeInherited: true,
                serializationNameFormat: SerializationNameFormat.CamelCase);
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
            SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true));
            SupportedEncodings.Add(new UnicodeEncoding(bigEndian: false, byteOrderMark: true, throwOnInvalidBytes: true));
        }
        public override bool CanReadType(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            return true;
        }
        public override bool CanWriteType(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            return true;
        }
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
        {
            return Task.FromResult(this.DeserializeFromStream(type, readStream));
        }
        private object DeserializeFromStream(Type type, Stream readStream)
        {
            try
            {
                using (var reader = new StreamReader(readStream))
                {
                    MethodInfo method = typeof(JSON).GetMethod("Deserialize", new Type[] { typeof(TextReader), typeof(Options) });
                    MethodInfo generic = method.MakeGenericMethod(type);
                    return generic.Invoke(this, new object[] { reader, mJilOptions });
                }
            }
            catch
            {
                return null;
            }
        }
        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, TransportContext transportContext)
        {
            var streamWriter = new StreamWriter(writeStream);
            JSON.Serialize(value, streamWriter, mJilOptions);
            streamWriter.Flush();
            return Task.FromResult(writeStream);
        }
    }
}
替換預設Json序列化庫:
using RRPService.WebApi.Comm;
using System.Web.Http;
using System.Web.Mvc;

namespace RRPService.WebApi.App
{
    /// <summary>
    /// web api 服務
    /// </summary>
    public class WebApiApplication : System.Web.HttpApplication
    {
        /// <summary>
        /// 服務啟動
        /// </summary>
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
            HttpConfiguration fConfig = GlobalConfiguration.Configuration;
            fConfig.Formatters.Remove(fConfig.Formatters.JsonFormatter);
            fConfig.Formatters.Insert(0, new JilFormatter());
        }
    }
}