JavaScripttestingV8

function add(x, y) { return x + y; } console.time("time1"); for (var i = 0; i < 90000000; ++i) { add(1, 2); add('a','b'); } console.timeEnd("time1"); function addText(x, y) { return x + y; } function addNumber(x, y) { return x + y; } console.time("time2"); for (var i = 0; i < 90000000; ++i) { addNumber(1, 2); addText('a','b'); } console.timeEnd("time2"); 

结果是:time1:1481ms,time2:102ms,

我在nodejs上运行这个testing,但我不知道为什么第一个testing运行比第二个慢。

这是因为由于参数types的改变而导致罩壳下的去通风化。 要知道这一点,我们必须知道V8是什么威胁:

内联

这是一个重要的优化,对于提升性能至关重要。 它用函数体replace函数调用来加速执行。 如果函数的大小很小,它将被内联。 这假设在函数调用中,参数是固定的。

Deoptimisation

V8在某些假设下做了优化。 如果它是错误的,它必须撤消这些优化,以便它能够正确运行代码。 去最佳化是不好的,因为它需要时间,被replace的代码性能较差。

为了看到这个实际运行的代码--trace_opt --trace_opt_stats --trace_deopt --trace-inlining --trace_deopt

 [deoptimize context: cbf30f14679] [marking addText 0xcbf30fc5ca0 for recompilation, reason: small function, ICs with typeinfo: 1/1 (100%)] [optimizing: addText / cbf30fc5ca1 - took 0.058, 0.092, 0.000 ms] Compiled: 1 functions with 42 byte source size in 0.150000ms. [marking addNumber 0xcbf30fc5ce8 for recompilation, reason: small function, ICs with typeinfo: 1/1 (100%)] [optimizing: addNumber / cbf30fc5ce9 - took 0.019, 0.033, 0.000 ms] Compiled: 2 functions with 84 byte source size in 0.202000ms. [marking 0x2c9408e1b3d0 for recompilation, reason: not much type info but very hot, ICs with typeinfo: 1/12 (8%)] Inlined addNumber called from . Inlined addText called from . [optimizing: / 2c9408e1b3d1 - took 0.131, 0.229, 0.000 ms] Compiled: 3 functions with 898 byte source size in 0.562000ms. time1: 126ms **** DEOPT: at bailout #11, address 0x0, frame size 192 [deoptimizing: begin 0x2c9408e1b3d1 @11] translating => node=111, height=32 0x7fff72081080: [top + 104] <- 0x2c9408e1b4e9 ; [sp + 32] 0x2c9408e1b4e9 <an Object> 0x7fff72081078: [top + 96] <- 0x58df1704121 <undefined> ; literal 0x7fff72081070: [top + 88] <- 0x58df1704121 <undefined> ; literal 0x7fff72081068: [top + 80] <- 0x58df1704121 <undefined> ; literal 0x7fff72081060: [top + 72] <- 0x58df1704121 <undefined> ; literal 0x7fff72081058: [top + 64] <- 0x58df1704121 <undefined> ; literal 0x7fff72081050: [top + 56] <- 0x23522b3122be ; caller's pc 0x7fff72081048: [top + 48] <- 0x7fff720810b0 ; caller's fp 0x7fff72081040: [top + 40] <- 0x2c9408e1b0d9; context 0x7fff72081038: [top + 32] <- 0x2c9408e1b3d1; function 0x7fff72081030: [top + 24] <- 0x2c9408e1b389 ; [sp + 40] 0x2c9408e1b389 <JS Function add> 0x7fff72081028: [top + 16] <- 0x2c9408e1b2f9 ; [sp + 48] 0x2c9408e1b2f9 <JS Function addText> 0x7fff72081020: [top + 8] <- 0x2c9408e1b341 ; [sp + 56] 0x2c9408e1b341 <JS Function addNumber> 0x7fff72081018: [top + 0] <- 0 ; rbx (smi) [deoptimizing: end 0x2c9408e1b3d1 => node=111, pc=0x23522b364aa0, state=NO_REGISTERS, alignment=no padding, took 0.076 ms] [removing optimized code for: ] [marking add 0x2c9408e1b388 for recompilation, reason: small function, ICs with typeinfo: 1/1 (100%)] [optimizing: add / 2c9408e1b389 - took 0.013, 0.024, 0.000 ms] Compiled: 4 functions with 939 byte source size in 0.599000ms. [marking 0x2c9408e1b3d0 for recompilation, reason: hot and stable, ICs with typeinfo: 2/12 (16%)] Inlined addNumber called from . Inlined addText called from . Inlined add called from . Inlined add called from . [optimizing: / 2c9408e1b3d1 - took 0.100, 0.194, 0.000 ms] Compiled: 5 functions with 1753 byte source size in 0.893000ms. time2: 1759ms 

由于参数改变,第一个循环得到优化,运行时间更长。 它不能被caching命中/未命中解释,因为没有读/写。

资料来源: http : //floitsch.blogspot.in/2012/03/optimizing-for-v8-inlining.html

我认为这是关于caching内存。 在1日,JavaScript不知道函数“ add ”做什么。 但在第二个JavaScript了解'addNumber'返回x和y和' addText '的总和返回x+''+y