代码示例:一些简单技巧优化JavaScript编译器工作详解,让你写出高性能运行的更快JavaScript代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码示例:一些简单技巧优化JavaScript编译器工作详解,让你写出高性能运行的更快JavaScript代码相关的知识,希望对你有一定的参考价值。

告诉你一些简单的技巧来优化javascript编译器工作,从而让你的JavaScript代码运行的更快。尤其是在你游戏中发现帧率下降或是当垃圾回收器有大量的工作要完成的时候。

单一同态:

当你定义了一个两个参数的函数,编译器会接受你的定义,如果函数参数的类型、个数或者返回值的类型改变编译器的工作会变得艰难。通常情况下,单一同态的数据结构和个数相同的参数会让你的程序会更好的工作。

function example(a, b) {
  // 期望a,b都为数值类型
  console.log(++a * ++b);
};

example(); // 不佳
example(1); // 仍然不佳
example("1", 2); // 尤其不佳

example(1, 2); // 很好

展开:

编译器会在编译的时候求出变量的值并且展开它(最佳实践),因此在程序执行前可以尽量多的表达信息。常量和变量一样可以被展开,只要它们没有用任何的与运行期有关的运算。

const a = 42; // 很容易展开
const b = 1337 * 2; // 可以求值
const c = a + b; // 也可以求值
const d = Math.random() * c; // 只能展开‘c‘
const e = "Hello " + "Medium"; // 其他类型的值也可以

// 展开前
a;
b;
c;
d;
e;

// 展开后
// 会在编译的时候做好这些!
42
2674
2716
Math.random() * 2716
"Hello Medium"

函数内联:

JIT编译器会找出你的代码中哪些部分是经常执行的。在编译的时候通过将函数分成小块来将代码块内联并且热追踪函数之后代码会执行的更快。

// 以下这些会内联
// [?] 单一的返回语句
// [?] 返回总是一样的
// [?] 返回时单一同态的
// [?] 参数是单一同态的
// [?] 函数体是一个单一的语句
// [?] 不是包裹在另一个函数体内
// ...
function isNumeric(n) {
  return (
    n >= 48 && n <= 57
  );
};

let cc = "8".charCodeAt(0);

// 内联前
if (isNumeric(cc)) {

}

// 内联之后
if (cc >= 48 && cc <= 57) {

}

Declarations:

避免在频繁调用的函数里声明函数/闭包或对象。对象(也包括函数,对象)会被压到堆里,垃圾回收器会影响这个堆,那里有很多 wat和wut 需要确定下一步(像释放与否)

相反,声明一个变量会很快,因为它们是被压到栈里。比如,一个函数会有自己的栈,与函数相关的变量都会压到这个栈里,无论何时这个函数退出,栈也随着释放。

// 欠佳
function a() {
  // 决不再函数里面申明函数
  // 会在每次调用函数分配资源
  let doSomething = function() {
    return (1);
  };
  return (doSomething());
};

let doSomething = function() {
  return (1);
};

// 很好
// 在函数外申明 ‘doSomething‘
// 因此可以只调用它,而不是
// 在每次调用‘b‘去申明和调用
function b() {
  return (doSomething());
};

参数:

函数调用的代价是昂贵的(如果编译器不能内联它们)。尝试去使用尽可能少的参数并且不在函数体内修改参数。

function mul(a, b) {
  return (arguments[0]*arguments[1]); // 欠佳, 很慢
  return (a*b); // 很好
};

function test(a, b) {
  a = 5; // 欠佳, 不修改参数标识
  let tmp = a; // 很好
  tmp *= 2; // 可以修改伪造的 ‘a‘
};

数据类型:

尝试尽可能多的取用数值和布尔类型,它们在比较操作中比其他基本类型要快很多。比如,声明一个字符串类型会偷偷的造成一大堆垃圾数据,因为字符串是一个复杂的有很多预设属性的对象。

同时,避免操作负数和多位小数的双精度浮点数。

const ROBOT = 0;
const HUMAN = 1;
const SPIDER = 2;

let E_TYPE = {
  Robot: ROBOT,
  Human: HUMAN,
  Spider: SPIDER
};

// 欠佳
// 避免在大任务中缓存字符串(最好在一般中场景也不)
if (entity.type === "Robot") {

}

// 很好
// 编译器会算出数值表达式
// 没有深度计算会更快
if (entity.type === E_TYPE.Robot) {

}

// 完美
// 右侧的二元表达式也是可以被展开的
if (entity.type === ROBOT) {

}

严格和抽象运算符:

尝试使用三等号操作如“===”(严格的)而不是 “==” (宽松的, 抽象的)。执行严格的运算符保证编译器去预设一个明确的值,而不用以多种情况去比较语句。(比如 n>0=^true),这样会导致更好的性能方案。

严格条件:

JavaScript提供了很棒的语法糖来允许你比如“if (a) then bla”这样的代码。这种情况下,编译器必须去以多种类型去比较“a”来确定是否为真,因为它不知道是那种类型的结果。当然,你应该使用这些很棒的语法糖,但是在快速执行的复杂的有多个返回语句的函数(如 null或者Object)中,你应该考虑以下建议。

有毒:

以下列表里的语言特性,会较少或阻止代码优化过程。

  • eval

  • with

  • try/catch

对象:

对象实例通常会尝试共享一个隐藏的类,谨慎的给一个实例化的对象添加一个成员变量,因为这样会创建一个新的隐藏类并且对编译器来说这会复杂很多(对你也会一样)

// 隐藏类‘hc_0‘
class Vector {
  constructor(x, y) {
    // 编译器找到并且期望的成员声明在这
    this.x = x;
    this.y = y;
  }
};

// 两个vector对象共享隐藏类‘hc_0‘
let vec1 = new Vector(0, 0);
let vec2 = new Vector(2, 2);

// 欠佳,vec2这样会创建新的隐藏类‘hc_1‘
vec2.z = 0;

// 很好,编译器知道这个成员
vec2.x = 1;

循环:

缓存你的数组长度属性,并且使用数组作为一个单一同态的类型。通常避免使用“for..in”或者在数组上循环,因为这会很慢。

循环语句中continue 和 break 语句会比if语句体更快。保持你的循环干净,把所有的东西打包成一个子函数,这样编辑器感觉会更舒服。同时,使用预增操作符(_++ i 代替 i ++_)会有一点点的性能提升。

let badarray = [1, true, 0]; // 欠佳, 不要混合类型
let array = [1, 0, 1]; // 好的用法

// 不好的选择
for (let key in array) {

};

// 更好的
// 但是总是缓存数组大小
let i = 0;
for (; i < array.length; ++i) {
  key = array[i];
};

// 很好
let i = 0;
let key = null;
let length = array.length;
for (; i < length; ++i) {
  key = array[i];
};

写在最后FOR Freedom | 知识就应该被开放的获取,看看外边的世界,以及IT这一行,少不了去Google查资料,最后,安利一个V——PN代理。一枝红杏 VPN,去Google查资料是绝对首选,连接速度快,使用也方便。我买的是99¥一年的,通过这个链接(http://my.yizhihongxing.com/aff.php?aff=2509)注册后输上会员中心得优惠码,平摊下来,每月才7块钱,特实惠。

本文标签 JavaScript编译器 JavaScript优化 JavaScript技巧 JavaScript编译器原理

转自 SUN‘S BLOG - 专注互联网知识,分享互联网精神!

原文地址 : 代码示例:一些简单技巧优化JavaScript编译器工作详解,让你写出高性能运行更快的JavaScript代码

相关阅读:如何在程序开发项目中选择合适的 JavaScript 框架,节省时间和成本的9款极佳的JavaScript框架介绍
相关阅读:网站环境apache + php + mysql 的XAMPP,如何实现一个服务器上配置多个网站?

相关阅读:什么是工程师文化?各位工程师是为什么活的?作为一个IT或互联网公司为什么要工程师文化?

相关阅读: 程序员有用:2017最新能上Google的hosts文件下载及总结网友遇到的各种hosts问题解决方法及配置详解

相关阅读:移动端UI设计越来越流行的高斯模糊(Gaussian blur)和毛玻璃效果(磨砂效果),如何使用Android RenderScript简单实现?

相关BLOG:SUN’S BLOG - 专注互联网知识,分享互联网精神!去看看:www.whosmall.com




以上是关于代码示例:一些简单技巧优化JavaScript编译器工作详解,让你写出高性能运行的更快JavaScript代码的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 性能优化技巧分享

JavaScript 性能优化技巧分享

高性能的 JavaScript 代码,优化技巧分享

高性能的 JavaScript 代码,优化技巧分享

103前端 | JavaScript 性能优化技巧分享

15个JavaScript优化技巧