标签存档: C#

在 .NET Core 3.0 中实现 JIT 编译的 JSON 序列化,及一些心得与随想

源码:https://github.com/Martin1994/JsonJitSerializer

NuGet:https://www.nuget.org/packages/MartinCl2.Text.Json.Serialization/

简介:Just-in-time 编译的 JSON 序列化

.NET Core 3.0 即将正式发布,其中一项令人振奋的功能是 corefx 集成了一个 JSON 库用来替代 JSON.NET,目前我按照 namespace 称这套库为 System.Text.Json。

这一套 JSON 库吸取了一部分 JSON.NET 的教训,将 API 的功能尽可能分离。例如它除了提供了 Object 与 String/Stream 之间的序列化与反序列化的高层 API 之外,还提供了逐 token 读写的底层 API。这为第三方开发者实现自己的 JSON 库提供了极大的方便。

了解到这一点后我意识到可以用这套底层 API(具体来说是 Utf8JsonWriter)来实现一个 just-in-time 编译(本质上其实是 IL generation)的 JSON 序列化库。

为何 JSON 序列化可以从 JIT 中受益呢?

System.Text.Json 实现 JSON 序列化的步骤是:

  1. 利用反射读出需要序列化的 class 的结构;
  2. 缓存每个需要序列化的 property,包括其名字(用 UTF-8 存储)、getter method 以及对应的 converter;
  3. 每次需要序列化的时候逐条读取这个结构化的缓存并利用 Utf8JsonWriter 序列化为 JSON stream。

可以注意到步骤 2 到 3 其实有点类似于解释执行的脚本语言。既然是解释执行,那自然可以有其对应的 JIT 优化,将解释的内容直接编译成可执行的代码。这样可以省去一些存取的开销和动态类型检查的开销。具体可以减小多少开销可以参照 benchmark 的结果:

Method Mean StdDev Median Min Max Gen 0/1k Op Gen 1/1k Op Allocated Memory/Op
System.Text.Json_Async 592.6 ns 1.3711 ns 592.6 ns 590.9 ns 594.8 ns 0.0471 304 B
MartinCl2.Text.Json_Async 346.0 ns 1.6620 ns 345.4 ns 344.4 ns 349.2 ns 0.0239 152 B

继续阅读 »

Lambert W function 数值计算

由于一些很蠢的原因,我写了一份完全用不着的用于计算 Lambert W function 的 C# 代码. 具体原理是很粗暴的牛顿法求解,但有几个特别处理的地方:

首先是估算. W0比较好处理,其实随便给个初始值就好,我这里选择了偏移后的 ex. 而 W-1 则比较特殊,首先在 x < -2 的部分变成了 concave 的,而且越往左斜率越小,所以一律从 x = -2 开始尝试;而在 -2 < x < -1 的区间内其实也是随便给个初始值就好,我这里选择了偏移后的 cos 函数.

其次是精度处理. 通过 log2x 做差可以求出二进制下的有效数位,然而当 y 值较大的时候其实并不能把完整的 52 位双精度浮点数的小数部分求完整,大概只能求到 47 位左右,所以这里我保守选择了 42 位有效数字.

继续阅读 »

.NET Core 调用 native library 的 project.json 写法

太长不看版:

一点废话:最近在用 ASP.NET Core 练手,想把去年 CS246 (C++) 的期末大作业做个 web interface. 当时选做了国际象棋,整个 C++ 代码从设计到完成,还附带一个不带 WebSocket 的用 ASP.NET Core beta5 (当时还叫 ASP.NET 5) 写的简易 web interface 作为附加分,一共也就用了 50 小时 (虽然忘记做王车移位时不能被将的判断了) 其中还有至少 4 小时花在了将 还处在 beta 的 ASP.NET Core 部署在 Amazon Linux 上. 而现在,我花在这个 web interface 上的时间可能都超过 100 小时了,看来核心业务逻辑果然是只占有非常少的比例啊…

这次要说的是,如果 C# 中要调用 native library,也就是要用 DllImport,那在 project.json 中应该如何导出这个 dll. 撰写此文的时候是 2016/09/10 版本是 .NET Core 1.0. (按照微软的尿性谁知道下个版本这么写还对不对)

继续阅读 »

Amazon Linux 编译安装 mono 并后台运行 ASP.NET5 应用(supervisor)

目前 ASP.NET5 环境仅对 Ubuntu 支持得比较好,而使用 yum 的几个 Linux 则需要花一些时间去安装了(理论上讲 mono 提供了 yum 的包,但实际安装的时候报缺少 libpng15.so,并没有找到任何方法修复). OS X 和 Windows 当然是一路绿灯并没有什么问题. 不巧的是我的 Amazon EC2 跑的是 Amazon Linux,折腾了一个礼拜才最终搞定.

首先当然是安装 mono. 安装过程可以参考 mono 官方的教程. (需要先安装 git 和 make)

注意:编译安装 mono 需要花费较长的时间.

继续阅读 »