我们不缺少JSON的序列化库,但我们缺少一个性能非常好的库,这对于网站来说非常重要。今天我发现了Jil。
他是开源的代码: https://github.com/kevin-montrose/Jil
在他主页上有详细的介绍其性能的表现,我这里就不转述了,他最重要的特点就是性能,Emit那当然不会少了,当想让他超越其他的库光一个Emit肯定不行,他还有很多其他的优化。
- 公共缓冲区
为介绍GC的压力,他使用了诸如builder.CommonCharBuffer这样的功能缓冲,builder.CommonStringBuffer也是这样的应用。
- 内联
很多的方法,都标记了[MethodImpl(MethodImplOptions.AggressiveInlining)]以便编译器尽可能的内联。
- 减少计算
比如将int转换为string,原先的代码是这样写的。
1 [MethodImpl(MethodImplOptions.AggressiveInlining)] 2 static void _CustomWriteInt(TextWriter writer, int number, char[] buffer) 3 { 4 // Gotta special case this, we can't negate it 5 if (number == int.MinValue) 6 { 7 writer.Write("-2147483648"); 8 return; 9 } 10 11 var ptr = InlineSerializer<object>.CharBufferSize - 1; 12 13 var copy = number; 14 if (copy < 0) 15 { 16 copy = -copy; 17 } 18 19 do 20 { 21 var ix = copy % 10; 22 copy /= 10; 23 24 buffer[ptr] = (char)('0' + ix); 25 ptr--; 26 } while (copy != 0); 27 28 if (number < 0) 29 { 30 buffer[ptr] = '-'; 31 ptr--; 32 } 33 34 writer.Write(buffer, ptr + 1, InlineSerializer<object>.CharBufferSize - 1 - ptr); 35 }
是不是觉得已经很好了,但是他们还不断进取,改成这样:
1 [MethodImpl(MethodImplOptions.AggressiveInlining)] 2 static void _CustomWriteInt(TextWriter writer, int number, char[] buffer) 3 { 4 var ptr = InlineSerializer<object>.CharBufferSize - 1; 5 6 uint copy; 7 if (number >= 0) 8 copy = (uint)number; 9 else 10 { 11 writer.Write('-'); 12 copy = 1 + (uint)~number; 13 } 14 15 do 16 { 17 var ix = copy % 100; 18 copy /= 100; 19 20 var chars = DigitPairs[ix]; 21 buffer[ptr--] = chars.Second; 22 buffer[ptr--] = chars.First; 23 } while (copy != 0); 24 25 if (buffer[ptr + 1] == '0') 26 ++ptr; 27 28 writer.Write(buffer, ptr + 1, InlineSerializer<object>.CharBufferSize - 1 - ptr); 29 }
其中,那个DigitPairs是什么呢?
1 struct TwoDigits 2 { 3 public readonly char First; 4 public readonly char Second; 5 6 public TwoDigits(char first, char second) 7 { 8 First = first; 9 Second = second; 10 } 11 } 12 13 private static readonly TwoDigits[] DigitPairs; 14 15 static Methods() 16 { 17 DigitPairs = new TwoDigits[100]; 18 for (var i=0; i < 100; ++i) 19 DigitPairs[i] = new TwoDigits((char)('0' + (i / 10)), (char)+('0' + (i % 10))); 20 }
是不是想法很高呢?
- 减少判断
原先的方法是这样的
1 static bool IsWhiteSpace(int c) 2 { 3 // per http://www.ietf.org/rfc/rfc4627.txt 4 // insignificant whitespace in JSON is defined as 5 // \u0020 - space 6 // \u0009 - tab 7 // \u000A - new line 8 // \u000D - carriage return 9 10 return 11 c == 0x20 || 12 c == 0x09 || 13 c == 0x0A || 14 c == 0x0D; 15 }
可以这样改,哈哈,其实我想这么改,不知道对不对?因为我觉得大多数情况下不是空白,所以一直要判断4次才能返回,而我改成这样:
1 static bool IsWhiteSpace(int c) 2 { 3 // per http://www.ietf.org/rfc/rfc4627.txt 4 // insignificant whitespace in JSON is defined as 5 // \u0020 - space 6 // \u0009 - tab 7 // \u000A - new line 8 // \u000D - carriage return 9 10 return 11 c < 0x21 && ( 12 c == 0x20 || 13 c == 0x09 || 14 c == 0x0A || 15 c == 0x0D); 16 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2006-07-24 从LinQ看我们的ORM设计