JavaScript 性能优化 --By Google V8 Team Manager
原文:https://developers.google.com/v8/?hl=zh-CN
Be Prepared before writing code[9:35]
Understand how V8 optimzes Javascript;
Write code mindfully;
Learn you tools and how they can help you;
Be Prepared - Hidden Classes[10:30]
Hidden Classes Make JavaScript Faster.
(注:Hidden Class 可以理解为VM内部实现对描述抽象类的描述,共享隐藏类才能让VM更高效)
Limit Compile-time type information
It's expensive to reason about JavaScript types at compile time...
- V8 internally creates hidden classes for objects at runtime.
- Objects with the same hidden class can use the same optimzed generated code.
Initialize all object members in constructor functions;
Always Initialize members in the same order;
(If you add members in different orders, you create a different tree of hidden classes.
And at the end, you'll have objects with two different hidden classes that can't use the same optimized code)
Be Prepared - Numbers[15:30]
We use a technique called tagging. So inside of V8 we pass around values of 32-bit numbers and objects.
But we want to be able to use the same 32 bits to represent both. And that way we can have one code path that can handle, in many cases, the objects and integers. So what we do is we use the bottom bit.
And each of the values have s special meaning. If the bit is se, it's an object pointer. If it's clear, it's what we call small integer or smi. And that's a 31-bit signed integer. Now if you have a numeric value that you're passing around, assigning to a member that is bigger -it's a numeric value that's bigger than 31 signed bits - then it doesn't fit in one of these smis. And we have to create what's called a box for it. We box the number. We turn it into a double and we create a new object to put that number inside of it. And what follows from that is the next speed trap to avoid, which is make sure, whenever possible, you use 31-bit signed numbers for performance critical calculations.
Prefer numberic values that can be represented as 31-bit signed integers.
Be prepared - Arrays[17:25]
- Fast Elements: linear storage for compact key sets.
- Dictionary Elements: hash table storage otherwise.
Use contiguous keys starting at 0 for Arrays. (
Don't pre-allocate large Arrays(e.g. > 64K elements) to their maxium size, instead grow as you go.
Don't delete elements in arrays, especially numberic arrays.
Double Array Unboxing
- Array's hidden class tracks elements types
- Arrays contraining only doubles are unboxed
- Unboxing causes hidden class change
Initialize using array literals for small fixed-sized arrays
Preallocate small arrays to correct size before using them
Don't store non-numeric values(objects) in numeric arrays
Be prepared - Full Compiler[26:36]
V8 has tow compilers
- "Full" compiler can generate good code for any Javascript
- Optimizing compiler produces great code for most JavaScript
"Full" compiler Starts Executing Code ASAP
- Quickly generates good but not great JIT code
- Assumes(almost) nothing about types at compilation time
- Uses Inline Caches(or ICs) to refine knowledge about types while program runs
Inline Caches(ICs) handle Types Efficiently
- Type-dependent code for operations
- Validate type assumptions first, then do work
- Change at runtime via backpathcing as more types are discovered
Monomorphic Better Than Polymophic
- Operations are monomophic if the hidden class is always the same
- Otherwise they are polymorphic
function add(x,y) {
return x + y;
}
add(1,2); //+ in add is monomorphic
add("a", "b") //+ in add becomes polymorphic
Prefer monomorphic over polymorphic whenever is possible.
Type Feedback Makes Code Faster
- Types taken from ICs
- Operations speculatively get inlined
- Monomophic functions and constructors can be inlined entirely
- Inlininig enables other optimizations
Logging What Gets Optimized
d8 --trace-opt prime.js
logs names of optimized functions to stdout
Not Everything Can Be Optimized
Some features prevent the optimizing compiler from running(a "bail-out")
Avoid the speed trap
Optimizing compiler "bail-out" on functions with try{} catch{} blocks.
Maximizing Performance With Exceptions
function perf_sensitive() {
//Do performance-sensitive work here
}
try{
perf_sensitive()
} catch(e) {
//handle exceptions here
}
How to Find Bailouts
d8 --trace-bailout prime.js
logs optimizing compiler bailouts
Invalid assumptions lead to deoptimization[37:55]
Deoptimization...
- ...throws away optimized code
- ...resumes execution at the right place in "full" compiler code
- Reoptimization might be triggered again later, but for the short term, execution slows down.
Passing V8 Options to Chrome
"/Applicaitons/Google Chrome.app/Contents/MacOS/Google Chrome" \--js-flags="--trace-opt --trace-deopt --trace-bailout"
Avoid the speed trap
Avoid hidden class changes in functions after they are optimized
Identify and Understand[39:50]
"Identify and Understand" for V8
- Ensure problem is JavaScript
- Reduce to pure JavaScript(no DOM!)
- Collect metrics
- Locate bottleneck(s)
Prime Generator -- Profile It
%out/ia32.release/d8 prime.js --prof 287107
using teh built-in sampling profiler
- Takes sampe every millisecond
- Writes v8.log
What to expect from the primes Code
function Primes() {
...
this.addPrime = function(i) {
this.primes[this.prime_count++] = i;
}
this.isPrimeDivisible = function(candidate) {
for(var i = 1; i <= this.prime_count; ++i) {
if(candidate % this.primes[i]) == 0) {
return true;
}
}
return false;
}
};
function main() {
p = new Primes();
var c = 1;
while (p.getPrimeCount() < 25000) {
if(!p.isPrimeDivisible(c)) {
p.addPrime(c);
}
c++;
}
print(p.getPrime(p.getPrimeCount()-1));
}
Prediction: Most Time Spent in main
- All properties and functions monomorphic
- All numeric operations are SMIs
- All functions can be inlined
- No deoptimizations or bailouts
(输出省略 @42:50)
Can you spot the bug?
this.isPrimeDivisible = function(candidate) {
for(var i = 1 ; i <= this.prime_count; ++i) {
if (candidate % this.primes[i] == 0) return true;
}
return false;
}
(Hint: primes is an array of length prime_count)
% out/ia32.release/d8 primes-2.js --prof
287107 (省略)
JavaScript is 60% faster than C++
C++
% g++ primes.cc -o primes
% time ./primes real 0m2.955s
user 0m2.952s
sys 0m.001s
JavaScript
% time d8 primes-.js real 0m1.829s
user 0m1.827s
sys 0m0.010s
JavaScript is 17% slower than optimized C++
Fix What Matters[49:59]
Optimize Your Algorithm
this.isPrimeDivisible = function(candidate) {
for(var i = 1 ; i < this.prime_count; ++i) {
var current_prime = this.primes[i];
if(current_prime*current_prime > candidate){
return false;
}
if (candidate % this.primes[i] == 0) return true;
}
return false;
}
Final Results
(输出省略)
That's more than a 350x Speed-up!
Keep Your Eyes on the Road
- Be prepared
- Identify and Understand the Crux
- Fix What matters
JavaScript 性能优化 --By Google V8 Team Manager的更多相关文章
- JavaScript性能优化篇js优化
JavaScript性能优化篇js优化 随着Ajax越来越普遍,Ajax引用的规模越来越大,Javascript代码的性能越来越显得重要,我想这就是一个很典型的例子,上面那段代码因为会被频繁使用, ...
- JavaScript性能优化
如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...
- javascript性能优化-repaint和reflow
repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,不会影响到dom结构渲 ...
- 摘:JavaScript性能优化小知识总结
原文地址:http://www.codeceo.com/article/javascript-performance-tips.html JavaScript的性能问题不容小觑,这就需要我们开发人员在 ...
- Javascript 性能优化的一点技巧
把优秀的编程方式当成一种习惯,融入到日常的编程当中.下图是今天想到的一点Javascript 性能优化的技巧,分享一下,抛砖引玉.
- JavaScript性能优化小窍门汇总(含实例)
在众多语言中,JavaScript已经占有重要的一席之地,利用JavaScript我们可以做很多事情 , 应用广泛.在web应用项目中,需要大量JavaScript的代码,将来也会越来越多.但是由于J ...
- JavaScript性能优化小知识总结(转)
JavaScript的性能问题不容小觑,这就需要我们开发人员在编写JavaScript程序时多注意一些细节,本文非常详细的介绍了一下JavaScript性能优化方面的知识点,绝对是干货. 前言 一直在 ...
- JavaScript 性能优化技巧分享
JavaScript 作为当前最为常见的直译式脚本语言,已经广泛应用于 Web 应用开发中.为了提高Web应用的性能,从 JavaScript 的性能优化方向入手,会是一个很好的选择. 本文从加载.上 ...
- javascript性能优化之避免重复工作
javascript最重要也最根本的性能优化标准之一是避免工作,避免工作又包括两点,第一,不做不必要的工作,第二,不做重复的已经完成的工作.第一部分可以通过代码重构完成,第二部分不做重复的工作有时候难 ...
随机推荐
- Java:静态导入
静态导入 importStatic 当类重名时,需要指定具体的包名. 当方法重名时,需要指定具体的类或对象名. 举例如下: import java.util.*; import static java ...
- 大众点评开源分布式监控平台 CAT 深度剖析
一.CAT介绍 CAT系统原型和理念来源于eBay的CAL的系统,CAT系统第一代设计者吴其敏在eBay工作长达十几年,对CAL系统有深刻的理解.CAT不仅增强了CAL系统核心模型,还添加了更丰富的报 ...
- nginx添加nginx_mod_h264_streaming-2.2.7模块编译报错
报错ngx_http_streaming_module.c:158: 错误:‘ngx_http_request_t’ 没有名为 ‘zero_in_uri’ 的成员.这需要修改nginx_mod_h26 ...
- excel读取 工具类
package cn.yongche.utils; import java.io.File; import java.io.FileInputStream; import java.io.IOExce ...
- Linux Java 环境变量设置
对整个机器:所有用户 1,在/etc/profile 文件末尾加入 export JAVA_HOME=/var/opt/jdk1.7.0_04 export PATH=$JAVA_HOME/bin:$ ...
- SPOJ 1739 Yet Another Equation(Pell方程)
题目链接:http://www.spoj.com/problems/EQU2/ 题意:给出方程x^2-n*y^2=1的最小整数解. 思路:参见金斌大牛的论文<欧几里得算法的应用>. imp ...
- Kafka安装与实验
接上面一篇文章: http://www.cnblogs.com/charlesblc/p/6038112.html 主要参考这篇文章: http://www.open-open.com/lib/vie ...
- Android使用 LruCache 缓存图片
摘要:在你应用程序的UI界面加载一张图片是一件很简单的事情,但是当你需要在界面上加载一大堆图片的时候,情况就变得复杂起来. 使用图片缓存技术 在 你应用程序的UI界面加载一张图片是一件很简单的事情,但 ...
- Trianglify – 五彩缤纷的 SVG 背景图案
Trianglify 是一个能够生成五颜六色的三角形图案的 JavaScript 库,可以用来作为 SVG 图像和 CSS 背景.它的灵感来自于 Btmills 的 Geopattern,并使用 d3 ...
- EASYUI+MVC4通用权限管理平台--前言
经过多年的管理信息系统的开发工作,吸取了工作中遇到的一些问题,经过自己的总结,形成了一套比较完整的管理信息系统的通用权限管理基础开发平台. 在软件的开发过程中我们首先需要解决的是UI问题,其次是浏览器 ...