Swift(八)-函数内联

692 阅读2分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

函数内联

函数内联是一种编译器优化技术,它通过使用方法的内容替换直接调用该方法,从而优化性能;

Xcode中的编译器优化

  • OC编译器优化

image.png

Debug模式下默认None(不优化);Release模式下默认Fastest,Smallest(最快最小)优化方案;最终编译出的可执行文件体积更小,运行更快;

  • Swift编译器优化

image.png

Debug模式下默认No Optimization(不优化);Release模式下默认Optimize for Speed优化方案;

详细优化效果请查看编译器优化链接 文章中的介绍;

函数内联方式

  • 将确保有时内联函数,这是编译器的默认行为,我们无需执行任何操作,Swift编译器可能会自动内联函数作为优化。
  • always将确保始终内联函数。通过在函数前添加@inline(__always)来实现此行为;
@inline(__always) func test() {
    print("test")
}
  • never将永远不会内联函数。通过在函数前添加@inline(never)来实现;
@inline(never) func test() {
    print("test")
}
  • 如果函数很长并且想避免增加代码段大小,请使用@inline(never)

函数内联在实际开发中的运用

如果对象只在声明的文件中可见,我们可以使用private或者fileprivate进行修饰。编译器会对private或者fileprivate对象进行检查,确保没有其他继承关系的情形下,自动添加final标记,从而使对象获得静态派发的特性(fileprivate只允许在定义的原文件中进行访问;private只允许在定义的声明中访问;)

我们查看以下示例代码:

image.png

接下来我们将Swift编译器优化调整到:

image.png

我们运行效果:

iShot2022-01-08 11.39.54.gif

我们发现change()方法的断点没有执行到;

test函数仅仅只是调用了changeName方法,所以符号已经被编译器优化掉,我们无法看到其调用;Person类也没有继承关系,那么编译器会给changeName方法添加final标识,那么changeName符号也将会被优化掉;所以我们的断点无法被执行;