当你把纯功能语言的绝对安全和优雅与现代低等语言的原始执行速度结合起来时,就像发现空间和时间是密不可分地联系在一起的:一个全新的维度为你打开了.
在之前的文章中, 我引入了一个编译器后端, 它将纯正脚本的绝对数学安全 带到了仍然在PHP上运行的70%的网络上。
目的是证明我们不必牺牲现代的安全 和人类基因组学 仅仅因为我们的目标是一个运行时间, 乍一看,不是最自然的。
今天,我们正研究的是正相反的一端。
如果PHP是关于最终可移植性和遗留相容性,那么当我们希望纯活金属速度时会发生什么?
当我们想要真正多核心的货币, 静态的本土二进制, 和一个为极端高通量设计的垃圾收集器时, 会发生什么?
向我最近的项目之一问好:gopurs,一个超优化的纯脚本到去编译器.
让我马上破坏故事的结局: 通过将纯正的高级语义纯洁度与现代Go的原始执行力相结合, 最终编译的代码与 Chez 计划在纯计算基准上相符。
是的,"切斯计划"(Chez Scheme),功能AOT编译(即数十年的编译器优化)的绝对历史捍卫者之一.
这将会是系列中一篇更短的文章, 但这里是一个快速的版本的故事...
打破AOT天花板:TAST如何改变一切历史,将动态或高度多态的功能语言(如PureScript或Haskell)编译为像Go这样的静态打字语言一直是一个噩梦.
更年长的尝试往往依赖于将一切绘制到去(或)去.
虽然有效,但是一种表演祭.
你给一个原始的值 都装入了盒子 然后逃到堆积地 给Go的垃圾收集器造成了巨大的压力 为了解决这个问题,最初使用平面结构(被标记的结合,由V8所启发),将东西多放在堆放上.
速度快得多 但还不够 真正的瓶颈是缺乏结构类型信息:PureScript的标准AST去除类型.
此为已打入的抽象语法树(TAST)所入.
依靠纯斯克丽特编译器和辉煌的自定义分叉(比您在这里能找到),将深层类型的信息一直保存到代码生成阶段.
这使得编译器可以进行严格的单态化,例如.
热道上零拳.
零头顶.
抽象在编译时完全融化,只留下了Go编译器能够积极优化的发光-快需要的循环.
无所畏惧的货币:满足高罗提内斯。
PureScript最大的长处之一是它的monad:处理同步效应的强大而可调和的方法.
在JavaScript世界中,被仔细地映射到被单线所读出的事件循环.
但Go没有单行本事件圈.
Go有goroutines和真实的,共享的并列主义跨越多个OS线程.
而不是试图伪造一个类似JS事件循环, 地图和直接到本土goroutines。
这意味着当您写入标准,纯纯的脚本一个同步代码时,您就含蓄地免费获得真正的多核心执行.
我以大量CPU负荷的工作量作为基准(运行10个平行的Fibonacci计算).
在JS(V8)中,事件循环被封住,10个任务以大约~15,000 ms相继执行.
在"去"(Go)中,这10项任务会自动被分配到机器的10个CPU核心上,以~1,250ms完成.
对于完全相同的纯脚本代码来说,它大约是12x快.
这是开发者体验的绝对梦想,不是吗?
你写纯的,数学上证明的抽象, 后端管弦在硬件水平上的平行。
你不需要关心低级机械,太常.
FFI没有痛苦:WebAssembly parser A语言仅能与其生态系统一样好,并交叉汇编
