代码示例:一些简单技巧优化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

时间: 2024-08-02 02:46:03

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

数据结构 - 简单选择排序(simple selection sort) 详解 及 代码(C++)

数据结构 - 简单选择排序(simple selection sort) 本文地址: http://blog.csdn.net/caroline_wendy/article/details/28601965 选择排序(selection sort) : 每一趟在n-i+1个记录中选取关键字最小的记录作为有序序列中第i个记录. 简单选择排序(simple selection sort) : 通过n-i次关键字之间的比较, 从n-i+1个记录中选出关键字最小的记录, 并和第i个记录交换. 选择排序需

JavaScript对象类型详解

JavaScript对象类型详解 JavaScrtip有六种数据类型,一种复杂的数据类型(引用类型),即Object对象类型,还有五种简单的数据类型(原始类型):Number.String.Boolean.Undefined和Null.其中,最核心的类型就是对象类型了.同时要注意,简单类型都是不可变的,而对象类型是可变的. 什么是对象 一个对象是一组简单数据类型(有时是引用数据类型)的无序列表,被存储为一系列的名-值对(name-value pairs).这个列表中的每一项被称为 属性(如果是函

Javascript 严格模式详解

Javascript 严格模式详解 作者: 阮一峰 日期: 2013年1月14日 一.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode).顾名思义,这种模式使得Javascript在更严格的条件下运行. 设立"严格模式"的目的,主要有以下几个: - 消除Javascript语法的一些不合理.不严谨之处,减少一些怪异行为; - 消除代码运行的一些不安全之处,保证代码运行的安全: - 提高编译器效率,增加运行速度

javascript工具--控制台详解(转自 阮一峰博客)

javascript工具--控制台详解(转自 阮一峰博客) 大神这篇博客是写在2011年,主要介绍 "Firefox" 浏览器插件 "Firebug" 的操作,如今主流浏览器对控制台都已经提供了很好的支持.我自己用的最多是谷歌的 "chrome" 浏览器,下面也用 "chrome" 浏览器来调试. 一.显示信息的命令 console.log();  //控制台输入 网页中不会输出 console.info();  //一般信息

JavaScript数组方法详解

JavaScript数组方法详解 JavaScript中数组的方法种类众多,在ES3-ES7不同版本时期都有新方法:并且数组的方法还有原型方法和从object继承的方法,这里我们只介绍数组在每个版本中原型上的方法,本文举例介绍了从ES3到ES7几乎所有的数组方法.这大概是最全的数组方法详解了.希望读者能从中有所收获. 一.各版本数组方法一览表 数组方法名 对应版本 功能 原数组是否改变 pop() ES3- 删除最后一位,并返回删除的数据 是 push() ES3- 在最后一位新增一或多个数据,

JavaScript(2)---DOM详解

JavaScript(2)---DOM详解 一.DOM概念 什么是DOM DOM全称为文本对象模型(Document Object Model),它定义了所有HTML元素的对象和属性,以及访问他们的方法.它的主要作用包括: 改变HTML 元素 , 改变HTML属性 , 改变CSS 样式,对页面中的所有事件做出反应. 1.DOM 节点树 概念 DOM模型将整个HTML文档看成一个树形结构,并用document对象表示该文档,树的每个子节点表示HTM档中的不同内容. 如图 上图对应的html代码如下

让python代码运行的更快

原文地址:http://infiniteloop.in/blog/quick-python-performance-optimization-part-i/ 往往小的改变却能带来大的性能提升, 下面说下python中的几点性能优化. 1.使用timeit模块 2.减少函数的调用次数 3.使用xrange代替range 4.''.join()代替+,+= 5.while 1 代替 while True 6.列表解析>for循环>while循环 7.使用局部变量 8.创建生成器和使用yield 9

javascript 操作cookies详解

javascript 操作cookies详解 这段操作cookies的方法我使用很久了,但是一直一来没遇到什么问题,今天在做一个在第一个页面保存了cookies,第二个页面获取或者第三个页面获取的功能中,发现了方法的局限性,比如,第一个页面路径为 http://xxxxx/cyb-car2016/h5OfficeWorker/index,第二个页面路径为 http://xxxxx/cyb-car2016/h5AlertController/index,其中除了域名是一样之外,还有一个命名空间不一

Discuz论坛写出的php加密解密处理类(代码+使用方法)

PHP加密解密也是常有的事,最近在弄相关的东西,发现discuz论坛里的PHP加密解密处理类代码,感觉挺不错,在用的时候,要参考Discuz论坛的passport相关函数,后面我会附上使用方法,先把类代码帖上来: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 <?php /*