查看原文
其他

文件I/O优化技巧

2016-06-03 Unity官方 Unity官方平台
一般来说,所有工程都会有对文件进行读写的操作。如果你不仅是要存储少量字节(例如JSON文件),就有必要考虑性能问题了。因为这种情况下很容易写出低效率的文件读写代码,而且编译器和Unity都无法帮助你优化。今天这篇文章将分享文件读写代码中一些常见的误区,希望对大家有所帮助。

.NET API提供了很多完善的写入文件系统相关的类。Stream抽象类和其子类FileStream,还有File类,带有静态函数Open以及很方便的读写函数如BinaryReader和BinaryWriter。C#语言本身提供了using语法可以方便地关闭文件流、文件读写对象实例和文件句柄。这类代码使用便利,安全系数高,容易实现:




基本来说,文件操作可以归纳为以下五个步骤:
  1. 打开文件:File.Open

  2. 读取字节:stream.Read

  3. 写入字节:stream.Write

  4. 查询位置: stream.Position 或 stream.Seek

  5. 关闭文件:stream.Dispose 或 stream.Close


如果反编译FileStream类,你会发现stream.Position和stream.Seek其实没有什么区别,仅仅是API叫法上的不同。还有,stream.Dispose和stream.Close也基本上没什么区别,都能关掉文件。

得益于streams,readers,writers的便利性,想要测试它们的性能也很方便。进行读写操作只需调用一个函数即可,但这些读写操作函数的性能消耗可大不相同。接下来我针对这些不同的读写方式写了一个测试程序,下面是程序将要做的工作:
  • 写入20MB,每次写入4KB的数据块

  • 写入20MB,每次写入1字节

  • 读取20MB,每次读取4KB的数据块

  • 读取20MB,每次读取1字节

  • 数次查找流的某个位置,次数与数据块的读写次数相同

  • 数次打开某个文件,次数与数据块的读写次数相同


测试脚本如下:





新建Unity工程,在Assets目录下新建TestScript.cs脚本并复制以上代码。然后在默认的空场景中将TestScript附加到Camera游戏对象上,最后编译。注意编译平台使用64位,在非Development模式下编译,画质设置为最快,分辨率设为最低(640x480)。测试环境如下:
  • 2.3 Ghz Intel Core i7-3615QM

  • Mac OS X 10.11.2

  • Apple SSD SM256E, HFS+ format

  • Unity 5.3.0f4, Mac OS X Standalone, x86_64, non-development

  • 640×480, Fastest, Windowed


测试结果如下:




真是有着天壤之别,因此我单独提取出了最快的三个数据,得到了第二张图表。
可以看出,以数据块的方式进行读写操作的效率非常之高。虽然你可能不会一个一个字节地去写,但却有可能以4字节(整数)或类似大小为数据块单位进行写入操作。所以尽可能以较大的数据块为单位进行操作,这将提高38倍的写入效率,205倍的读取效率!
流查找(不论设置Position或调用Seek)不会进行字节读写,但这种操作是有代价的,虽然没有其它类型的操作那样多,它需要相当于读取4KB数据块三分之一的资源。所以最好避免这种查找操作,尽量线性读写文件,这样才能在各层面最大限度地发挥缓存的优势。
最后,打开或关闭文件同样不需要读取任何字节,但需要的时间会很长。事实证明,非常之长!打开和关闭文件需要的时间是以字节块写入整个文件所需时间的6.5倍,是字节块方式读取整个文件所需时间的40倍。考虑到读写操作的重要性,以及打开和关闭文件是操作系统的唯一需求,所以,除非特别需要,不要打开关闭文件。而且操作大文件要比操作多个小文件更好。
以上包括了关于I/O性能的一些建议,如有疑问,欢迎来下方评论区留言。

本文来源于:jacksondunstan.com

原作者:Jackson Dunstan


Unity官方活动


为了更好地为大家提供本地化的服务,进一步了解大家使用Unity以及相关服务的情况,我们将正式开展本年度第一次《Unity问卷调查》(点击蓝字参与)所有填写完整并提交的参与者,将有机会获得我们赠送的Unity官方纪念礼品


问卷调查地址:https://www.wenjuan.com/s/zaEZVv/


近期Unity官方将在上海举办官方教育培训活动,为参会者提供系统的Unity技能培训,梳理Unity相关的整个技能树以更好的应用到教学中。


如果您是院校老师(点击活动名称报名)

欢迎参与:Unity官方教育培训

活动时间:6月14日 - 6月16日

活动地点:上海


延展阅读

Unity全新产品及定价6月出炉

Asset Store疯狂促销来袭,最低四折!

Unity图像特效教程|保留指定颜色

UnityEvent与C#事件系统性能对比

Unity中如何中断C#脚本的无限循环


我们还会分享更多Unity相关的技术内容在Unity官方中文论坛(forum.china.unity3d.com),请保持关注!



点击“阅读原文”进入Unity官方中文论坛!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存