加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

.NET 性能优化的技巧

发布时间:2019-08-22 07:15:45 所属栏目:建站 来源:gejigeji
导读:最大化内联 内联是将方法体(method body)复制到调用站点的技术,这样我们就可以避免跳转、参数传递和寄存器保存/恢复等繁琐过程。除了节省这些之外,内联还是实现其他优化的必要条件。 不不过Roslyn(C#的编译器)没有内联代码,它是通过JIT实现的,大多数优

当复杂对象包含众所周知的字段(如int,Guid,string)时,代码生成器将直接插入对这些类型的手动编码编解码器的调用,而不是调用CodecProvider来检索该类型的IFieldCodec 实例。这允许JIT内联那些调用,并避免了虚拟/接口间接。

在运行时专门化泛型类型

与上面类似,代码生成器可以生成在运行时使用专门化的代码。

预先计算常数值以消除某些分支

在序列化期间,每个字段都带有一个标头,通常是一个字节。它会告诉解串器哪个字段是编码的。此字段标题包含3条信息:字段的规格(固定宽度、长度前缀、标记分隔、引用等),字段的模式类型(预期、众所周知、以前定义的、编码)用于多态,并将最后3位专用于编码字段id(如果它小于7)。在许多情况下,可以确切地知道在编译时这个标头字节是什么。如果字段具有值类型,那么我们就知道运行时类型永远不能与字段类型不同,并且始终知道字段id。

因此,我们通常可以保存计算标头值所需的所有工作,并可以直接将其作为常量嵌入到代码中。这样可以节省分支并且通常会消除大量的中间语言代码。

选择适当的数据结构

通过切换到结构数组,很大程度上消除了索引和维护集合的成本,并且参考跟踪不再出现在基准测试中。这有一个缺点,对于大型对象图,这种新方法可能较慢。

选择合适的算法

Hagar花费大量时间对可变长度整数进行编码/解码,这种方法被称为varints,varints是用一个或多个字节序列化整形的一种方法,以减小有效载荷的大小。许多二进制序列化器使用这种技术,包括协议缓冲区。甚至.NET的BinaryWriter也使用这种编码。下面是参考资料的一小段:

  1. protected void Write7BitEncodedInt(int value) { 
  2.     // Write out an int 7 bits at a time.  The high bit of the byte, 
  3.     // when on, tells reader to continue reading more bytes. 
  4.     uint v = (uint) value;   // support negative numbers 
  5.     while (v >= 0x80) { 
  6.         Write((byte) (v | 0x80)); 
  7.         v >>= 7; 
  8.     } 
  9.     Write((byte)v); 

我想指出ZigZag编码对于包含负值的有符号整数可能更有效,而不是强制转换为uint。

这些序列化器中的变量使用称为Little Endian Base-128或LEB128的算法,该算法每字节编码多达7位。它使用每个字节的最高有效位来指示是否跟随另一个字节(1 =是,0 =否)。这是一种简单的格式,但可能不是最快的。不过PrefixVarint更快,使用PrefixVarint,所有来自LEB128的1都是在有效载荷的开头一次性写入的。这可能让我们使用硬件内在函数来提高这种编码和解码的速度。通过将大小信息往前移,我们也可以从有效载荷中一次读取更多字节,从而减少内部压力并提高性能。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读