一次性初始化完整对象属性比先创建再添加属性更优吗?

文章讨论了V8引擎如何使用隐藏类来优化对象处理,当对象形状改变时会创建新隐藏类。内联缓存(InlineCache,IC)是V8提升函数执行效率的策略,通过缓存调用点的关键数据减少查找时间。尽管这些机制能提高速度,但实际项目中应关注性能瓶颈,而非过度优化。

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

请看下面例子:

let point = {};
%DebugPrint(point);
point.x = 100;
%DebugPrint(point);
point.y = 200;
%DebugPrint(point);

使用d8执行:

 d8 --allow-natives-syntax test.js 

得到:


DebugPrint: 0x986080c5b35: [JS_OBJECT_TYPE]
 - map: 0x0986082802d9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - ...


DebugPrint: 0x986080c5b35: [JS_OBJECT_TYPE]
 - map: 0x098608284ce9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - ...
 - properties: 0x0986080406e9 <FixedArray[0]> {
    #x: 100 (const data field 0)
 }


DebugPrint: 0x986080c5b35: [JS_OBJECT_TYPE]
 - map: 0x098608284d11 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - p
 - ...
 - properties: 0x0986080406e9 <FixedArray[0]> {
    #x: 100 (const data field 0)
    #y: 200 (const data field 1) 

可以得到如下结论:

  • 如果对象的形状没有发生改变,那么该对象就会一直使用该隐藏类;如果对象的形状发生了改变,那么 V8 会重建一个新的隐藏类给该对象。
  • 因为每次为对象添加一个属性时,V8 都会为该对象重新设置隐藏类。所以,尽量使用字面量一次性初始化完整对象属性。

综上,这个文章标题的答案是 yes。

加餐:
V8 会想尽一切办法来压缩这个查找过程,以提升对象的查找效率。这个加速函数执行的策略就是内联缓存 (Inline Cache),简称为 IC。
IC 的原理很简单,直观地理解,就是在 V8 执行函数的过程中,会观察函数中一些调用点 (CallSite) 上的关键的中间数据,然后将这些数据缓存起来,当下次再次执行该函数的时候,V8 就可以直接利用这些中间数据,节省了再次获取这些数据的过程,因此 V8 利用 IC,可以有效提升一些重复代码的执行效率。

最后:
虽然我们分析的隐藏类和 IC 能提升代码的执行速度,但是在实际的项目中,影响执行性能的因素非常多,找出那些影响性能瓶颈才是至关重要的,你不需要过度关注微优化,你也不需要过度担忧你的代码是否破坏了隐藏类或者 IC 的机制,因为相对于其他的性能瓶颈,它们对效率的影响可能是微不足道的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值