V8上的JavaScript测试

本文探讨了在V8引擎上,JavaScript测试中出现的一个现象:一个测试比另一个运行得慢,原因是参数类型变化导致的去优化。V8的内联和去优化机制被详细解释,去优化是因为引擎对函数的某些假设不成立。作者建议使用特定选项来查看去优化过程,并指出可能的内存缓存影响。文章最后提供了前端学习资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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");

结果是:时间1:1481 ms,时间2:102 ms,

想系统学习前端web的朋友,欢迎私信奕辰获取免费学习教程。

1.评论文章,没字数限制,一个字都行! 2.关注奕辰,成为的粉丝! 3.私信奕辰:“web”,“1”获取前端学习面试资料。

大家一起学习(群主会不定时更新学习资料,以及面试题文档)

或者可以添加我的个人微信号:wdnmd__xxx

小助理微信:lyf___1201

我在NodeJS上运行了这个测试,但是我不知道为什么第一个测试比第二个测试运行得慢。

问题由:菲奥玛


这是因为由于参数类型的改变,在引擎盖下发生了去优化。要了解这一点,我们必须了解优化V8的功能:

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

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

若要查看此操作,请运行带有选项的代码。

--trace_opt
--trace_opt_stats
--trace_deopt
--trace-inlining
[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

第一个循环由于参数变化而去优化,运行时间更长。它不能用缓存命中/误操作来解释,因为没有读/写。
讨论
我认为这是关于缓存内存的。在第一节中,javascript不知道函数‘add“”做什么?但是,在第二个javascript中,理解‘addNumber’返回x&y和‘addText“返回”x+’’+y

想系统学习前端web的朋友,欢迎私信奕辰获取免费学习教程。

1.评论文章,没字数限制,一个字都行! 2.关注奕辰,成为的粉丝! 3.私信奕辰:“web”,“1”获取前端学习面试资料。

大家一起学习(群主会不定时更新学习资料,以及面试题文档)

或者可以添加我的个人微信号:wdnmd__xxx

小助理微信:lyf___1201

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值