值类型优化
仓颉语言引入了值类型对象,值类型的局部变量在读写时无需 GC 相关屏障,在进行内存读写时,能够直接访问,无需考虑引用信息的变化。合理利用值类型语义,能有效加速程序运行。
值类型提供了更多数据排布和访问的方式。通过合理的数据结构设计,使得数据在访问上能够拥有优秀的空间/时间局部性,在运算、访问等操作上能够带来更大优势。如下图所示,类 A 的数组在访问数组内成员的成员变量时,需要进行 2 次 load,而对于值类型的数组,对于 A 里成员变量的访问时,仅需 1 次 load。
OSR(On Stack Replacement)优化对于值类型非常友好,在合理 OSR 的情况下,部分值类型数据能够直接打散到寄存器中,对于数据访问、运算等带来更大优势。例如下述示例,值类型 SA 对象,被打散成 a 和 b,而 a 和 b 都可以在寄存器中表示,而不用再进行重复的 load。后续再通过常量传播可以直接将 a 和 b 用常量表示。
struct A {
var a : UInt64 = 10
var b : UInt64 = 100
}
main() {
var SA = A()
var sum = 0
for (i in 0..100) {
sum += SA.a
}
return sum + SA.b
}
经过OSR优化,上述源码可以变换为下述形式,减少结构体成员变量访问操作
main() {
var a = 10
var b = 100
var sum = 0
for (I in 0..100) {
sum += a
}
return sum += b
}
值类型在分配时相比较引用类型更快,在回收时更快速、高效,跟随栈空间的回退,值类型自动回收,无需额外操作。
在引用类型下,会出现深拷贝,引入了额外的访存开销。使用值类型可以改造这类场景,就避免了间接寻址和深拷贝。尤其在处理基础类型时,如数字、布尔值等,将会带来更大优势。