【Unity优化】为C#定制联合(Union)提高序列化速度
来源:互联网 发布:淘宝客怎么关闭掉 编辑:程序博客网 时间:2024/06/03 23:50
序列化
很多时候,我们可以通过Protobuf之类的插件来执行序列化处理,不过如果你像我一样,对代码有洁癖的话,可能就会担心这些第三方插件的处理效率问题,有时候就会尝试自己手动处理序列化。还有一种情况就是,如果你的游戏是实时联网的,需要不断网络IO,此时还是保持洁癖比较好。
其实自己手动处理序列化也不是非常麻烦。只要针对数据对象和字节数组之间可以互相转化就可以了。
那么在自己手写序列化的过程中,遇到的一个问题就是怎样转换你的数据,比如最基本的整形、浮点型这些。
BitConvertor
在Unity中,有BitStream,然而好像没有什么用处,它们好像与Unet密切相关,而Unet目前生死未卜。
在CSharp中默认为我们提供了一个BitConvertor方法。通过它可以进行基础数据类型和字节数组之间的转换。然而我并不推荐你用它,这里我简单做了一个测试来解释原因。以下的代码都是放在一个组件的Update方法中去执行。
void testConvertFloatToBytes() { float f = 10; for (int i = 0; i < 1000; i++) { BitConverter.GetBytes(f); } }
这个方法在做从float到byte数组的转换。然而,你应该能看出来一些问题。它在不停制造出byte[],而数组都是个对象,因此它在不断产生GC Alloc。
如下图:
因此,当在需要连续不断进行序列化的时刻(网络游戏中),这个方法是不可以使用的。
使用联合(Union)
在CSharp中默认是没有联合(Union)的,然而我们可以构建出一个类似联合的结构体。
使用结构体布局(StructLayout)属性以及字段偏移(FieldOffset)属性就可以自己定制数据在结构体中的分布,从而定制出一个联合。
[StructLayout(LayoutKind.Explicit, Size = 4)]struct UNum{ [FieldOffset(0)] public byte b0; [FieldOffset(1)] public byte b1; [FieldOffset(2)] public byte b2; [FieldOffset(3)] public byte b3; [FieldOffset(0)] public int i; [FieldOffset(0)] public float f;}
此时,我们进行数据转换时,可以使用以下的方式进行转换:
protected byte[] m_datas; protected int m_dReader; void testConvertFloatToBytes_U() { float f = 10; for (int i = 0; i < 1000; i++) { UNum u = new UNum(); u.f = f; m_datas[m_dReader++] = u.b0; m_datas[m_dReader++] = u.b1; m_datas[m_dReader++] = u.b2; m_datas[m_dReader++] = u.b3; } }
这个方法不会产生任何的GC,因为它没有将结果放在小数组中,而是直接放入了一个整体缓冲区。
注意m_datas需要是足够大的缓冲区,m_dReader是缓冲区读取索引。
总结
当执行连续大量的序列化时,使用联合可以很好地避免GCAlloc产生,而且效率要比BitConvertor来的高。
- 【Unity优化】为C#定制联合(Union)提高序列化速度
- mysql表联合union优化为表连接join
- 虚拟现实Unity提高速度问题
- SQL联合查询优化 用union all来代替union
- SQL联合查询优化 用union all来代替union
- 解决union all 联合查询,速度慢的问题
- 优化Microsoft Access提高速度
- 优化Myeclipse大幅提高速度
- 优化sql提高查询速度
- 优化网站提高打开速度
- 优化Android Studio,提高速度
- 联合(union)
- union联合
- 联合(union)
- 联合(union)
- 联合union
- Union 联合
- 联合union
- MyBatis参数传入集合之foreach动态sql
- ThinkPHP5 select出来的结果是个对象?居然还可以以数组形式访问数据?
- 手写数字识别系统编程技巧
- “谈一谈网络编程学习经验“总结
- MySQL简单实例
- 【Unity优化】为C#定制联合(Union)提高序列化速度
- hadoop自定义分区
- Codeforces 688E The Values You Can Make【Dp】
- springmvc知识点总结
- Android 性能优化之布局优化
- ruby语法条件语句实例
- 最简单快速的Apache二级域名实现方法介绍
- 解决ScrollView嵌套ListView和GridView冲突
- java数据存储及读取的几种常用方法