使用订单文件提高应用程序性能

为您的应用下订单

介绍

iOS应用程序的二进制文件可能为数十兆甚至数百兆字节。 这么多的数据需要花费一些时间才能加载到内存中,这是隐藏的性能成本。 订单文件可加快将应用程序二进制文件加载到内存中的过程,从而提高整体性能。 要了解它们,我们首先必须看一下分页。

分页

操作系统将数据以页(即固定大小的块)(每个iPhone为16 KB)的大小加载到内存中。 每当调用一个函数或从二进制文件访问一条数据时,操作系统就会加载包含该函数的页面。 即使该功能仅占用页面的一小部分,操作系统仍将加载整个页面。 因此,如果存在碎片,即一起调用的函数驻留在许多不同的页面中,则将有加载页面的开销,将它们保存在内存中。 订单文件可以减少碎片。

什么是订单文件?

顺序文件是提供给链接器的文件,用于指定应将所有函数和数据放入二进制文件中的顺序。 如果可以将通常一起调用的功能(例如,所有在启动时调用的功能)组合在一起,则可以提高应用程序的性能。

注意:仅当您选择了所有性能低下的水果后,才能处理订单文件。 这是一个更为复杂的优化,无法保证您将获得多少加速。

确定应该是什么顺序

总览

排序的一种好方法是在第一次调用每个函数时。 因此,它可能以main开头,然后是-[AppDelegate applicationDidFinishLaunching:…]等。为此,我们可以使用coverage sanitizer ,这是一个编译器功能,其中每个被编译的函数都会在每次运行时调用全局处理程序。 然后,第一次使用任何特定功能调用处理程序时,我们会将其记录在列表中,然后将该列表写到文件中。

使用Coverage消毒器进行编译

在您的Xcode构建设置中,在“其他C标志”下添加-fsanitize-coverage=func,trace-pc-guard 。 如果您使用的是Swift,请在“其他Swift标志”下添加-sanitize-coverage=func并打开地址清理器(可以在方案设置中完成)。 对于要链接到主二进制文件的所有内容,请确保包括这些标志,例如Cocoapods。

在运行时记录

将此代码和此标头插入您的应用程序。 然后,尽可能多地使用该应用程序,并逐一浏览功能,从最受欢迎的功能开始到最受欢迎的功能结束。 最后,调用CLRCollectCalls() ,它将返回被调用函数的列表。 将此列表写到文件中,每个调用都单独行,然后将“ Order file”构建设置更改为该文件的路径。 然后,再次构建项目,并通过将列表与nm -j -p 比较,来验证它是否已重新排序。 两者应该匹配。

结论

订单文件可以减少内存消耗和CPU时间。 目前,它对于您的应用可能不是必需的或无用的,但它是您可以在需要时使用的另一种工具。 本文仅介绍如何在二进制文件中排序函数,但是如果有人要求,我也可以讨论如何在二进制文件中排序数据(例如,常量字符串)。