找回密码
 立即注册
查看: 219|回复: 2

[笔记] 提高Unity编译dll的速度

[复制链接]
发表于 2022-7-24 16:38 | 显示全部楼层 |阅读模式
前言

我们有一个Unity纯C#开发的mmo项目(使用ILRuntime热更,开发阶段跑纯C#),在开发到后期之后,每次修改C#代码编译时间在25秒左右,这部分的等待时间是很长的, 我在想有没有办法可以缩短这个编译时间。
编译dll时间分布:

  • assembly-csharp 20s
  • assembly-csharp-editor 0.88s
  • assembly reload 4.08s
如果把逻辑代码,抽离出来不放在Unity的目录下,通过visual studio编译这部分代码花费10s,抽离之后Unity编译时间为5s。也就是热更代码放Unity之后 assembly reload的时间变长了很多。
项目代码构成:

  • 不可热更代码,放在Unity的Asset目录
  • 可热更代码也是C#,通过ILRuntime热更
完整项目的Assembly-CSharp.dll有12.9MB,主要是protobuf的协议和配置表的entity数量非常多,还有非常多的养成系统代码,因为mmo游戏内容量很大。
当然在这之前我已经尝试过使用asm,因为这个项目有很多代码之间是相互依赖的,只有少部分代码进行asm化了,所以我想尝试还有没有其它可以缩短编译时间的方法。
Unity官方的增量编译

Unity2018.1官方提供增量编译插件,见Unity论坛:https://forum.unity.com/threads/unity-incremental-c-compiler-deprecated.523993/
在Unity的manifest文件中添加以下内容
{
    "dependencies": {
        "com.unity.incrementalcompiler": "0.0.30"
    },
    "registry": "https://staging-packages.unity.com"
}注意:目前官方已废弃此插件,原因是Unity2018.3中使用的C# 编译器比以往提高了5倍的速度,官方认为已经没有必要使用这个插件了,并且移除了这个插件。
而且我在Unity2019.3.7f1中添加上述package无效。
官方移除此插件的原话:https://forum.unity.com/threads/unity-incremental-c-compiler-deprecated.523993/page-9
You should not be using incremental compiler when you are using Unity 18.3. In terms of compilation speed, 18.3 is very very close to Incremental compiler speed and a lot more robust
Unity官方的其它做法

在unity的文档中还提到这两种可以减少dll的编译时间:

  • 把第三方库或不常改动的代码放到 Standard Assets或Plugins 目录下,这两个目录下的代码会最先编译,且不能依赖于外部其它脚本
  • 尽可能多的使用asm,在Unity2018.2中已支持。
注意:建议每一个asm中的代码是独立的,不依赖于外部,虽然Unity2019之后的版本asm之间可以相互引用
关于asm可以参考我的这篇博客《Unity的asm笔记》
增量编译或动态加载dll

微软的Roslyn

通过Roslyn构建自己的C#脚本 看起来像和lua一样,执行字符串就可以执行C#代码,看起来可以做到在修改C#的情况下不重新Unity Play就能执行,看完文章之后我还没有去研究。
Roslyn是.NET编译器平台,是微软的一组用于C#和VB语言的开源编译器和代码分析API,可以通过传统的命令行程序使用这些编译器,也可以通过.NET代码从本地获得这些API。Roslyn公开了用于代码的语法(词法)分析,语义分析,对CIL的动态编译以及代码发出的模块。
罗斯林(Roslyn)最显着的主要特征包括:

  • 通过API公开为服务的C#和Visual Basic语言的编译器。
  • 用于代码分析和重构的API 。
关于Roslyn的介绍摘自维基百科:Roslyn(编译器)
github增量编译库

Unity3D.IncrementalCompiler
从提交记录来看只支持到Unity5,在github找到另一个fork者的库已支持unity2018,但是clone下来后没有编译成功dll,所以放弃了。
网上搜索Roslyn Unity也是只支持到Unity5
插件

Roslyn C# - Runtime Compiler :收费插件,价格20美金
*Requires .Net 4.x API compatibility level*
Roslyn c#允许使用Roslyn编译器在运行时加载程序集和c#脚本,使您可以轻松地向项目添加modding(改装)支持或游戏内编程。此外,Roslyn c#还包括代码安全验证,允许您指定加载的代码必须遵守的许多安全限制,包括非法的名称空间和类型。这使得从未知来源加载第三方代码更加安全。包括一个基于小程序设计的游戏,其目标是通过编写执行方向决策的代码来导航鼠标走出迷宫。
查看Unity编译dll的耗时分布

Compiling Indicator - Wait Relaxed 免费插件,功能介绍:
编译指示器是一个小的通知窗口,当Unity编辑器开始编译时弹出。它显示了编译的进度和估计的完成时间。您还可以找到占用项目编译时间最多的程序集。
编译指示器了解项目的编译时间。因此,它的估计将会变得正确,因为它经历了更多的编译。您所要做的就是等待,直到编译指示器掌握了足够的信息。或者,要重置已学习的信息,您可以单击“清除数据库”按钮。
使用方法:导入到Unity之后,当C#代码有修改时,在右下角会弹出编译进度,编译完成之后点击一下就可以关闭



目前我的做法

放在Standard Assets

经过上面的尝试之后,目前是把用到的2个插件放在Standard Assets目录下,对sharpzip进行asm化,编译时间基本保持在24秒左右。
把框架代码asm化

框架代码抽出到独立目录中,进行asm化,关于asm可以参考我的这篇博客《Unity的asm笔记》
去掉不使用的package

去掉package.json中不需要用到的库,我在项目中只留下了package manager ui,时间减少了0.5s

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2022-7-24 16:45 | 显示全部楼层
想问问关于你们的ILRT,在研发阶段就按照ILRT标准开发了,还是准备在后期再进行代码整理?
发表于 2022-7-24 16:52 | 显示全部楼层
研发前期有调研过ILR,研发期代码就是分两个工程,后期根据性能指标调整
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-3 12:02 , Processed in 0.092952 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表