V8提升对象属性访问速度---快属性和慢属性

2023-12-29 12:57:43

V8提升对象属性访问速度—快属性和慢属性

在 JavaScript 中,对象就像一个字典,可以使用字符串作为键名,任意对象作为键值。早期的实现方式是使用字典来存储对象的属性。

字典是非线性的数据结构,查询效率会低于线性的数据结构,为了提高存储和查找的效率,V8 采用了一套复杂的存储策略。它将对象的属性分为常规属性(properties)和排序属性(elements)。

常规属性 (properties) 和排序属性 (element)

function Foo() { 
  this[100] = 'test-100' 
  this[1] = 'test-1' 
  this["B"] = 'bar-B' 
  this[50] = 'test-50' 
  this[9] = 'test-9' 
  this[8] = 'test-8' 
  this[3] = 'test-3' 
  this[5] = 'test-5' 
  this["A"] = 'bar-A' 
  this["C"] = 'bar-C'
}

var bar = new Foo()

for(key in bar){ 
  console.log(`index:${key} value:${bar[key]}`)
}

在这里插入图片描述

打印出来的属性顺序并不是我们设置的顺序

  • 设置的数字属性被最先打印出来了,并且是按照数字大小的顺序打印的;
  • 设置的字符串属性依然是按照之前的设置顺序打印的

之所以出现这样的结果,是因为在 ECMAScript 规范中定义了数字属性应该按照索引值大小升序排列,字符串属性根据创建时的顺序升序排列。

在这里我们把对象中的数字属性称为排序属性,在 V8 中被称为 elements,字符串属性就被称为常规属性,在 V8 中被称为 properties。

在这里插入图片描述

快属性和慢属性

??将不同的属性分别保存到 elements 属性和 properties 属性中,无疑简化了程序的复杂度,但是在查找元素时,却多了一步操作,比如执行 bar.B这个语句来查找 B 的属性值,那么在 V8 会先查找出 properties 属性所指向的对象 properties,然后再在 properties 对象中查找 B 属性,这种方式在查找过程中增加了一步操作,因此会影响到元素的查找效率。

??为了进一步提高查找效率,V8 采用了对象内属性(in-object properties)的策略。对象内属性是指将部分常规属性直接存储在对象本身中,而不是在单独的属性存储容器中。这样,在查找属性时,V8 可以直接从对象本身获取属性的值,而无需额外的查找步骤。

在这里插入图片描述

??采用对象内属性之后,常规属性就被保存到 bar 对象本身了,这样当再次使用bar.B来查找 B 的属性值时,V8 就可以直接从 bar 对象本身去获取该值就可以了,这种方式减少查找属性值的步骤,增加了查找效率。

??然而,对象内属性的数量是固定的,默认为10个。如果对象中的属性超出了对象内属性的空间,那么这些属性将被存储在常规属性存储容器中。虽然常规属性存储多了一层间接层,但它们可以自由地扩容。

??通常,保存在线性数据结构中的属性被称为快属性,因为可以通过索引快速访问属性。然而,如果添加或删除大量属性,线性数据结构的性能会受到影响。为此,当对象的属性过多时,V8 采用了慢属性的存储策略。慢属性使用非线性数据结构(词典)作为属性存储容器,所有属性的元信息都直接保存在属性字典中。

请添加图片描述

总结:
??V8 通过快属性和慢属性的存储策略,提高了对象属性的访问速度。快属性直接存储在对象内部,快速访问效率高。而慢属性则使用属性字典存储,适用于属性数量过多或频繁添加和删除属性的情况,以提高修改属性的效率。

???通过引入这两个属性,加速了 V8 查找属性的速度,为了更加进一步提升查找效率,V8 还实现了内置内属性的策略,当常规属性少于一定数量时,V8 就会将这些常规属性直接写进对象中,这样又节省了一个中间步骤。

??但是如果对象中的属性过多时,或者存在反复添加或者删除属性的操作,那么 V8 就会将线性的存储模式降级为非线性的字典存储模式,这样虽然降低了查找速度,但是却提升了修改对象的属性的速度。
?

文章来源:https://blog.csdn.net/m0_37820751/article/details/135286237
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。