杂谈-通过编译器优化代码

前段时间有人问我,如何考虑编译优化。我想了想,但是因为自己没有学过这方面的课程,也没有总结出成套的体系(毕竟自己一共就只吃了几年程序员的🍚),所以,只能告诉他,“把自己当做编译器的作者。当编译器的作者面对自己的代码时,他能做些什么”

扯淡结束,下面通过一个小例子讲讲“为什么 Objective-C 难以进行优化”。

Objective-C 是 C 的超集,语言创作者通过给 struct 添加了一些 function,把 struct 升级为了 class。当然,实际情况不会像我说的这样简单,肯定会更加复杂,但我这里只是讲和下文相关的内容。

struct 升级为了 class,function 也“一人得道鸡犬升天”地升级为了 method。

很多 iOS 开发者都无法区分“函数”和“方法”。实际上,把它们翻译为 function 和 method 可能区分度更高一些。

可以粗糙的用以下等式区别它们:

类 = 含有特殊字段的结构体 + 其它
method = function + 类的引用 + 其它

首先,稍微解释一下第一个等式。类经过编译后,会被打散到 mach-o 的多个地方。其中,一份信息会存储到 mach-o 的 __DATA,__objc_data 字段。

如下图。

Objective-C 中的 method 被编译后,会被当做函数处理,与此同此,编译后的 mach-o 文件也会保留一些特殊信息。

如下图,第一幅图表示:method 编译后,会在 段__TEXT,__text 生成一个对应的函数。第二幅图表示:这是一个函数。第三幅图表示:method 与 class 之间的关系会被存储到 段 __DATA,__objc_const

1
2
3

我们先回顾一下它们的用法。

简单来说,类似于 [[NSObject alloc]init] 的写法都是在调用 Objective-C 中“类”或“类的实例”的 method,而 int result = pow(x,y) 属于调用 function 的过程。

考虑这样一种情况,如果某个类,它的某些方法没有被编译器检测到调用,比如没有检测到[object aMethod]这种用法。编译器是否该把这个方法的实现从编译后的 mach-o 文件内移除,从而减小可执行文件的体积,提到可用的内存空间,加快载入速度?

答案是:“非常不推荐这样做”。Objective-C 是一门动态语言,除了直接调用外,还有大量的动态调用方式。仅仅因为编译器检测不到调用就进行移除是非常危险的行为。

再考虑这样一种情况,如果某个函数,它没有被编译器检测到被调用,比如没有检测到 int result = pow(0,0)。编译器是否该把这个函数的实现从编译后的 mach-o 文件内移除,从而减小可执行文件的体积,提到可用的内存空间,加快载入速度?

答案是:“非常推荐这样做”。虽然通过某些方案也可以动态调用
c 函数,但是,很显然,这样行为非常非常少,程序员有义务自己处理这种情况或者关闭优化器。

类似的,因为 Objective-C 可以动态添加 method 的原因,编译器不能直接把 [objc superMethod] 替换为 直接执行函数superMethod(objc,...),而是需要通过递归地查找方法列表,检测该方法是否被某一个父类动态添加了实现。

综上,一个动态性非常强的语言是很难依靠编译器作者的智慧进行优化的,所以,苹果才会从零开始发明一种新的编程语言。

参考文章:https://llvm.org/svn/llvm-project/cfe/branches/ggreif/CallInst-operands/test/CodeGenObjC/metadata-symbols-64.m

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,407评论 0 9
  • 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的...
    西木阅读 29,957评论 33 468
  • 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的...
    lylaut阅读 693评论 0 4
  • 转载:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麦子阅读 517评论 0 2
  • 本文转载自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex阅读 586评论 0 1
  • #幸福是需要修出来的~每天进步1%~幸福实修04班-31,08班03-陈莉梅-浙江永康# 20170908(82/...
    陈莉梅阅读 33评论 0 1
  • 我们仨依旧在打台球。刚开始,手有些生疏,后来隔三差五去一趟,熟练不少。 对于玩乐之事,我们男生似乎更容易上瘾。很多...
    两棵松阅读 324评论 9 5
  • 有人说:熟悉的地方没有风景,距离产生美,其实,彼此尊重,能够退一步即海阔天空。不知不觉过了这么些年,没留下些值得回...
    鹿妞阅读 189评论 0 0
  • 今日早读《黄帝内经》,有悟。古人对自我的认知,现在看来依然有借鉴之处。以前对古文没兴趣,读不下去。原因是好多字认不...
    开创新生活阅读 316评论 0 0