如何加快 MonoTouch 编译时间?

Posted

技术标签:

【中文标题】如何加快 MonoTouch 编译时间?【英文标题】:How to speed up MonoTouch compilation time? 【发布时间】:2012-12-07 09:44:34 【问题描述】:

那是well known

如果编译需要 15 秒,程序员会在编译器运行时感到厌烦,转而阅读 The Onion,这会吸引他们并扼杀数小时的工作效率。

我们的 MonoTouch 应用程序需要 40 秒才能在 Macbook Air 上以调试/模拟器配置进行编译。

我们的解决方案中有大约 10 个程序集。 我们还使用gcc_flags 链接一些本机库。

我确信有一些我不知道的优化编译时间的方法,这可能与引用、链接器等有关。

我问这个问题是希望比我有更多知识的人会编译(不是双关语)一个提示和检查事项列表,以减少调试构建的 MonoTouch 编译时间。

不要建议硬件优化或与MonoTouch 没有直接关系的优化。

【问题讨论】:

SSD,更多 RAM,更多内核,设置 ram 磁盘并从那里编译,例如用于 android 构建的 ccache... 你在运行什么操作系统,它是诚然,这个问题太宽泛了…… @t0mm13b:感谢您的光临。该问题在标题中包含“MonoTouch”,我也对其进行了标记。 MonoTouch 是仅适用于 OS X 的产品,用于使用 C# 构建 ios 应用程序。因此,我问的是 MonoTouch 特定的优化,而不是硬件/一般的东西。 【参考方案1】:

Xamarin.iOS 6.4 中的构建时间改进

Xamarin.iOS 6.4 具有 significant build time improvements,现在可以选择仅将更新的代码位发送到设备。自己看:

(来源:xamarin.com)

阅读更多内容并了解如何在 Rolf's post 中启用增量构建。

进化 2013 视频

可以在我在Evolve 2013 发表的Advanced iOS Build mechanics演讲视频中看到此内容的更新和扩展版本。

原答案

有几个因素会影响构建速度。但是,它们中的大多数对设备构建有更大的影响,包括您提到的托管链接器的使用。

托管链接器

对于设备Link all是最快的,其次是Link SDK和(最后)不要链接。原因是链接器可以比 AOT 编译器更快地消除代码(净增益)。此外,较小的 .app 将更快地上传到您的设备。

对于模拟器不链接总是更快,因为没有 AOT(使用 JIT)。除非您想测试它们,否则不应使用其他链接选项(它仍然比进行设备构建要快)。

设备技巧

构建单一架构(例如 ARMv7)比 FAT 二进制文件(例如 ARMv7 + ARMV7s)更快。更小的应用程序也意味着上传到设备的时间更短;

默认 AOT 编译器(单声道)比使用 LLVM 编译器快很多。但是后者会生成更好的代码,并且还支持 ARMv7s、Thumb2;

如果您的 .app 中捆绑了大型资产,则使用您的应用程序部署/上传它们(每次都必须签名)需要时间。我写了一个 blog post 来说明如何解决这个问题 - 如果您拥有大量资产,它可以节省大量时间;

在 MonoTouch 5.4 中实现了对象文件缓存。一些构建会快很多,但其他构建不会(当必须清除缓存时)更快(但绝不会变慢;-)。更多信息为什么经常发生这种情况here)。

调试构建需要更长的时间,因为符号,运行 dsymutil,并且由于它最终变得更大,因此需要额外的时间来上传到设备。

默认情况下(您可以将其关闭)发布版本会执行程序集的 IL 条带。这只需要一点时间 - 在将(较小的 .app)部署到设备时可能会恢复。

模拟器技巧

如前所述,尽量避免链接,因为这将花费更多时间并且需要复制程序集(而不是符号链接);

使用本机库比较慢,因为在这种情况下我们无法重用共享的 simlauncher 主可执行文件,需要让 gcc 为应用程序编译一个(这很慢)。

终于每当有疑问的时候了!我的意思是您可以将--time --time 添加到您的项目extra mtouch arguments 以在每次操作后查看时间戳:-)

【讨论】:

这就是我希望得到的答案:-)。谢谢你! 我很高兴它能从你的构建中减少几秒钟! @poupou 如果您不介意,我编辑了您的答案,包括一个指向 Rolf 帖子的链接,其中包含最近的改进。 现在是 2016 年,但我仍然需要 4-5 分钟才能将应用程序安装到设备上。只是想知道在 2012 年会花费多少小时。诚然,这不是一个小程序,但同样适用于 Android 的应用程序可以在 30 秒内在同一台机器上编译。 我很惊讶link all 实际上更快(由于 AOT)。每次重建(从 5 分钟到 1.5 分钟)时,它为我节省了 3 分钟【参考方案2】:

这并不是真正的答案,而是一个临时占位符,直到有更好的占位符。 我找到了this quote by Seb:

查看项目的构建选项并确保“链接器 行为”位于默认的“链接 SDK 程序集”。

如果它显示“不链接”,那么您将体验 非常 长构建 时间(其中很大一部分在 dsymutil 中)。

我不知道它是否仍然相关,因为当我选择此选项时,MonoDevelop 会显示一个警告标志,而且它似乎对性能影响不大。

【讨论】:

【参考方案3】:

你不能指望你的编译器在不了解它需要做的所有事情的情况下很快。更大的应用程序自然会花费更长的时间。不同的语言或相同语言的不同编译器可能会对编译代码所需的时间产生巨大影响。

我们有一个编译需要将近 2 分钟的项目。最好的解决方案是想办法减少编译代码的次数。

而不是尝试修复 1 行代码并一遍又一遍地重建。召集一群人一起讨论这个问题。或者创建一个包含 3 或 4 个您想要处理的事情的列表,完成它们然后进行测试。

这些只是一些建议,并不适用于所有情况。

【讨论】:

我明白编译需要时间。但我对 MonoTouch 提前编译器和链接器设计的了解还不够,无法判断什么是最耗时的。生成 Mono 软调试器指令是否耗时?不?运行dsymutil 怎么样?链接本机库?我应该为链接器使用三个选项中的哪一个?增加蹦床的数量会影响构建时间吗?这些是让我好奇的事情,如果有人知道答案,我不想自己测试所有配置。而且它们特定于 MonoTouch 的,因此是可以回答的。

以上是关于如何加快 MonoTouch 编译时间?的主要内容,如果未能解决你的问题,请参考以下文章

如何在模拟器中为 MonoTouch 应用程序生成 .dSYM?

如何分析 Monotouch 以查看运行时创建的蹦床数量(按类型)?

尝试在 MonoTouch.CoreGraphics.CGContext.DrawPDFPage 中 JIT 编译方法异常

如何加快 sass 编译速度?

编译器优化如何加快简单操作之间的时间?

如何加快 Rails Asset Pipeline 预编译过程?