Facebook开源JavaScript代码优化工具Prepack

5月4日,Facebook开源团队技术作者Joel Marcey在Hacker News社区发布一则《Prepack帮助提高JavaScript代码的效率》,引起了社区的广泛讨论

\\

官方宣称Prepack是一个优化JavaScript源代码的工具,实际上它是一个JavaScript的部分求值器(Partial Evaluator),可在编译时执行原本在运行时的计算过程,并通过重写JavaScript代码来提高其执行效率。Prepack用简单的赋值序列来等效替换JavaScript代码包中的全局代码,从而消除了中间计算过程以及对象分配的操作。对于重初始化的代码,Prepack可以有效缓存JavaScript解析的结果,优化效果最佳。

\\

以下五个概念可以帮助你更好地理解Prepack的运行机制:

\\
  • 抽象语法树(AST) \\
    Prepack运行在AST级别,使用Babel解析并生成JavaScript源代码。 \\
  • \

    具体执行(Concrete Execution) \\
    Prepack的核心是一个JavaScript解释器,它与ECMAScript 5几乎完全兼容,而且紧密地保持与ECMAScript 2016语言规范的一致性,你可以将Prepack中的解释器视为完全参照JavaScript实现的。

    \\

    解释器能够跟踪并撤销包括所有对象Mutation在内的结果,从而能够进行推测优化(Speculative Optimization)。

    \ \\
  • 符号执行(Symbolic Execution) \\
    除了对具体值进行计算外,Prepack的解释器还可以操作受环境相互作用影响的抽象值。例如Date.now可以返回一个抽象值,你可以通过helper辅助函数(如__abstract())手动注入抽象值。Prepack会跟踪所有在抽象值上执行的操作,在遇到分支时,Prepack会执行并探索所有可能性。所以,Prepack实现了一套JavaScript的符号执行引擎。 \\
  • 抽象释义(Abstract Interpretation) \\
    符号执行在遇到抽象值的分支时会分叉(fork),Prepack会在控制流合并点加入分歧执行(Diverged Execution)来实现抽象释义的形式。连接变量和堆属性可能会得到条件抽象值,Prepack会跟踪有关抽象值和型域(Type Domain)的信息。 \\
  • 堆序列化(Heap Serialization) \\
    当全局代码返回,初始化阶段结束时,Prepack捕获最终的堆并按顺序排列堆栈,生成直观的JavaScript新代码,创建并链接初始化堆中可访问的所有对象。堆中的一些值可能是抽象值的计算结果,对于这些值,Prepack将生成原始程序完成计算所执行的代码。 \

以下是官方提供的Prepack优化示例:

\\
/* Hello World */\// Input\(function () {\  function hello() { return 'hello'; }\  function world() { return 'world'; }\  global.s = hello() + ' ' + world();\})();\// Output\(function () {\  s = \"hello world\";\})();
\\
/* 消除抽象税 */\// Input\(function () {\  var self = this;\  ['A', 'B', 42].forEach(function(x) {\    var name = '_' + x.toString()[0].toLowerCase();\    var y = parseInt(x);\    self[name] = y ? y : x;\  });\})();\// Output\(function () {\  _a = \"A\";\  _b = \"B\";\  _4 = 42;\})();
\\
/* 斐波那契 */\// Input\(function () {\  function fibonacci(x) {\    return x \u0026lt;= 1 ? x : fibonacci(x - 1) + fibonacci(x - 2);\  }\  global.x = fibonacci(23);\})();\// Output\(function () {\  x = 28657;\})();
\\
/* 模块初始化 */\// Input\(function () {\  let moduleTable = {};\  function define(id, f) { moduleTable[id] = f; }\  function require(id) {\    let x = moduleTable[id];\    return x instanceof Function ? (moduleTable[id] = x()) : x;\  }\  global.require = require;\  define(\"one\
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值