ASP.NET Web API下对比测试Jil序列化性能
听闻Jil JSON序列化的速度相当快,所以决定做个简单测试。编码平台是Visual Studio 2013,浏览器是Firefox 39.0.3。
后台App启动时,创建了一个有100万条记录的List对象。有一个API方法返回这100万条记录。时间计时在前台,所以,总的耗时不只后台序列化时间,还包括将这100万条记录传输到前台并反序列化的时间。虽然不是纯粹的序列化时间,但能反应出二者。
下面是几次测试耗时记录:
测试次序 | 原生JSON耗时(秒) | Jil JSON耗时(秒) |
---|---|---|
1 | 6.249 | 4.239 |
2 | 5.911 | 3.902 |
3 | 6.037 | 3.854 |
4 | 5.997 | 3.862 |
5 | 6.033 | 4.419 |
6 | 5.982 | 3.717 |
7 | 5.966 | 3.721 |
8 | 6.045 | 2.984 |
9 | 6.568 | 3.673 |
10 | 5.945 | 3.667 |
11 | 6.018 | 3.169 |
12 | 6.033 | 3.782 |
平均 | 6.065 | 3.749 |
Jil要比原生的快61.8%,值得推荐。
注册使用Jil的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace ProductsApp
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
config.Formatters.RemoveAt(0);
config.Formatters.Insert(0, new JilFormatter());
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
注释掉代码中的这两行
config.Formatters.RemoveAt(0);
config.Formatters.Insert(0, new JilFormatter());
即可以恢复原生JSON序列化。其中的JilFormatter如下:
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;
using Jil;
namespace ProductsApp
{
public class JilFormatter : MediaTypeFormatter
{
private readonly Options _jilOptions;
//private MethodInfo _method;
public JilFormatter()
{
//要序列化的时间格式
_jilOptions = new Options(dateFormat: DateTimeFormat.ISO8601);
//媒体类型
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
//加入 UTF8Encoding 编码
SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true));
//加入 UnicodeEncoding 编码
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(DeserializeFromStream(type, readStream));
}
private object DeserializeFromStream(Type type, Stream readStream)
{
try
{
using (var reader = new StreamReader(readStream))
{
return JSON.Deserialize(reader, type, _jilOptions);
}
}
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, _jilOptions);
streamWriter.Flush();
return Task.FromResult(writeStream);
}
}
}
这段代码也是从网上直接抄来的,只另注释了一行未使用变量定义,哈哈。
下面是前台代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Product App</title>
<script src="Scripts/jquery-3.1.0.min.js"></script>
</head>
<body>
<div>
<p id="beginTime" />
<p id="endTime" />
<h2>All Products</h2>
<ul id="products" />
</div>
<div>
<h2>Search by ID</h2>
<input type="text" id="prodId" size="5" />
<input type="button" value="统计时间" onclick="calcTime();" />
<input type="button" value="Search" onclick="find();" />
<p id="product" />
</div>
<script type="text/javascript">
var uri = 'api/products';
$(document).ready(function () {
Send an AJAX request
//$.getJSON(uri).done(function (data) {
// // On success, 'data' contains a list of products.
// $.each(data, function (key, item) {
// // Add a list item for the product.
// $('<li>', { text: formatItem(item) }).appendTo($('#products'));
// });
//});
});
function formatItem(item) {
return item.Name + ': $' + item.Price;
}
function find() {
var id = $('#prodId').val();
$.getJSON(uri + '/' + id)
.done(function (data) {
$('#product').text(formatItem(data));
})
.fail(function (jqXHR, textStatus, err) {
$('#product').text('Error: ' + err);
});
}
function getTimeMi() {
var d = new Date();
return d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + "." + d.getMilliseconds();
}
function calcTime() {
$('#beginTime').text(getTimeMi());
$.getJSON(uri).done(function (data) {
$('#endTime').text(getTimeMi());
});
}
</script>
</body>
</html>
转载于:https://my.oschina.net/u/877388/blog/835362
ASP.NET Web API下对比测试Jil序列化性能相关推荐
- Asp.net Web Api开发 性能:使用Jil提升Json序列化性能
from:http://blog.csdn.net/sqqyq/article/details/51692342 看了几篇网上关于各种序列化工具的性能对比,在这里再粘贴下: 我们使用了ASP.NET ...
- Asp.net Web Api开发(第二篇)性能:使用Jil提升Json序列化性能
看了几篇网上关于各种序列化工具的性能对比,在这里再粘贴下: 我们使用了ASP.NET WEB API来提供RESTfull风格的接口给APP调用,默认序列化库用的是:Newtonsoft.Json 为 ...
- 使用Jil序列化JSON提升Asp.net web api 性能
JSON序列化无疑是Asp.net web api 里面性能提升最重要的一环. 在Asp.net web api 里面我们可以插入自定义的MediaTypeFormatter(媒体格式化器), 说白了 ...
- 重温.NET下Assembly的加载过程 ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线...
重温.NET下Assembly的加载过程 最近在工作中牵涉到了.NET下的一个古老的问题:Assembly的加载过程.虽然网上有很多文章介绍这部分内容,很多文章也是很久以前就已经出现了,但阅读之后发现 ...
- ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线
在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容.下面的类图描述了我们已经实现的组件及其之间的关系,貌似系统已经变得越来越复杂了. 其 ...
- ASP.NET Core Web API下事件驱动型架构的实现(二):事件处理器中对象生命周期的管理
在ASP.NET Core Web API下事件驱动型架构的实现(一):一个简单的实现中,我介绍了事件驱动型架构的一种简单的实现,并演示了一个完整的事件派发.订阅和处理的流程.这种实现太简单了,百十行 ...
- ASP.NET Core Web API下事件驱动型架构的实现(四):CQRS架构中聚合与聚合根的实现
在前面两篇文章中,我详细介绍了基本事件系统的实现,包括事件派发和订阅.通过事件处理器执行上下文来解决对象生命周期问题,以及一个基于RabbitMQ的事件总线的实现.接下来对于事件驱动型架构的讨论,就需 ...
- (四)Asp.net web api中的坑-【api的返回值】
(四)Asp.net web api中的坑-[api的返回值] 原文:(四)Asp.net web api中的坑-[api的返回值] void无返回值 IHttpActionResult HttpRe ...
- Asp.Net Web API 2第一课——入门
前言 Http不仅仅服务于Web Pages.它也是一个创建展示服务和数据的API的强大平台.Http是简单的.灵活的.无处不在的.你能想象到几乎任何的平台都会有HTTP服务库.HTTP服务可以涉及到 ...
最新文章
- Python 基础(6)(常用数据结构)
- Educational Codeforces Round 2 B. Queries about less or equal elements
- oracle的簇与簇表
- expected:instruction or directive
- 二维动态数组定义及二维静态数组与**P的区别
- 定位到元素后获取其属性_Selenium界面自动化测试(4)(Python):元素定位及操作...
- LeetCode MySQL 1853. 转换日期格式(日期格式化)
- CVPR 2020 论文大盘点-目标检测篇
- .net 裁剪图片(不压缩)
- 《Tensorflow 实战》(完整版,附源码)
- three.js几何体的旋转,缩放,平移
- 微信分身服务器验证失败咋办,微信好友验证发送失败原因分析及解决方法汇总...
- 用python制作动态二维码_用Python制作动态二维码
- xmlDocument是什么?(转)
- The Game C语言
- 【BUCTOJ训练: 质数的和与积(Python)】
- Matlab多项式和符号函数简介
- RN开发问题总结(一)
- html做人脸识别 博客,一个人脸识别+特效的小例子
- 2020计算机专业保研夏令营面经:北大信科计算机
热门文章
- Node.js实现网络新闻爬虫及搜索功能(四)
- 友豆火山CPG插件开发002-环境配置和第一个例子
- 揭秘!最快大数乘法运算
- 华为鸿蒙 HarmonyOS 2.0 手机开发者 Beta 来了,对开发者意味着什么?
- 关于-3db截止频率
- 无聊创意12306改变
- mysql meb备份_MySQL的企业备份(MEB)
- XSL3399我开通博客了谢多交流
- 记一次阿里电话面试| 技术征文
- [NIPS-18] Generalizing to Unseen Domains via Adversarial Data Augmentation