博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
能在编码时做的事,就不要推迟到运行时
阅读量:7004 次
发布时间:2019-06-27

本文共 1651 字,大约阅读时间需要 5 分钟。

TL.DR

软件是一个巨大的有限状态机。工程师日常做的bug修复、性能调优,本质上就是尽可能保证代码处于有序状态下。

不论OC还是Swift,都拥有强大的编译器作为辅助。尽可能多地将状态固定在编码时,就就减少了运行期的状态,使得软件的状态总数减少了。

状态总数少了,错误就少了,性能也就提升了。

Case 1:OC Runtime的

这个例子的关键点是性能

OC为了做到ABI兼容,改变了C、C++以来对象的内存结构,每个成员变量都需要两次寻址才能访问到。比如要获取obj的第n个变量的偏移地址,就要

*((&obj->isa.cls->data()->ro->ivars->first)[N]->offset);

看起来就慢爆了。

在实现上,LLVM为每个类的每个成员变量都分配了一个全局变量,用于存储该成员变量的偏移值。这样,访问每个变量需要两次寻址,先获取全局变量,再取全局变量的值作为地址找到真正的变量。

编译后的

obj->myInt = 42;

对应于如下的简单C语言代码

int32_t g_ivar_MyClass_myInt = 40;  // 全局变量*(int32_t *)((uint8_t *)obj + g_ivar_MyClass_myInt) = 42;

这就是为什么ivar_t.offset用int指针来存储偏移值,而不是直接放一个int的原因。

struct ivar_t {    int32_t *offset;  //注意,这里是指针    const char *name;    const char *type;        //...}

真正存放偏移值的地址是固定不变的,在编译时就确定了下来。因此才能用区区2条指令搞定动态布局的成员变量。

Case 2:矩阵相乘

这个例子的关键点是减少错误

Matrix

如图所示,要保证第一个矩阵中的列数必须与第二个矩阵中的行数相同。简单的做法是做运行时检查

struct Matrix {  let rows: Int  let columns: Int}func multiply(m1: Matrix, _ m2: Matrix) -> Matrix? {  // do the matrices have the correct sizes?  precondition(m1.columns == m2.rows)    // bunch of math...}

更好的做法是在编码时,就不允许出现行列不等的情况

protocol Dimension {  static var size: Int { get set }}func multiply
(m1: Matrix
, _ m2: Matrix
) -> Matrix
{ // bunch of math... return Matrix
()}

运行结果

struct NumExamples: Dimension { static var size = 20 }struct NumFeatures: Dimension { static var size = 10 }struct OneDimensional: Dimension { static var size = 1 }let A = Matrix
()let B = Matrix
()let C = multiply(A, B) // yay!let D = multiply(B, A) // compiler error
完整的优化过程不在本文的讨论范围内,感兴趣的可以看 。

参考链接

转载地址:http://gsytl.baihongyu.com/

你可能感兴趣的文章
[日常] 编写HTTP接口文档
查看>>
Android App开发技能图谱(转载)
查看>>
【转】Kotlin 和 Checked Exception
查看>>
Java基础-二进制以及字符编码简介
查看>>
树莓派GPIO控制RGB彩色LED灯
查看>>
T-SQL基础查询——单表查询
查看>>
Android中经常使用的bitmap处理方法
查看>>
ffmpeg超详细综合教程——摄像头直播
查看>>
Python3在指定路径下递归定位文件中出现的字符串
查看>>
iterm2退出时保存会话状态,下次打开恢复
查看>>
关于UNPIVOT 操作符
查看>>
图片人脸检测——OpenCV版(二)
查看>>
java字符编码转换
查看>>
DPDK virtio-user
查看>>
mp3
查看>>
scrapy-redis介绍(一)
查看>>
微信公众平台开发概述
查看>>
Migrate from ASP.NET Core 2.0 to 2.1
查看>>
利用git提交代码
查看>>
Elasticsearch的Java API做类似SQL的group by聚合。
查看>>