大家好!
“信息系统的安全性 ”课程将在2周内开始,因此今天我们要发布本文的第二部分,该文章的发布时间恰逢其发布。 您可以在
这里阅读第一部分。 因此,让我们开始吧。
内联缓存(IC)表单背后的主要思想是内联缓存或IC的概念。 它们是快速JavaScript的关键组件! JavaScript引擎使用IC来记住有关在何处查找对象属性的信息,以减少昂贵的搜索次数。

我们有一个
getX
函数,该函数将一个对象作为输入并从中加载
x
属性:
function getX(o) { return ox; }
如果在JSC中运行此函数,则会得到以下字节码:

第一个
get_by_id
从第一个参数
(arg1)
加载
'x'
属性,并将结果存储在
loc0
。 以下语句返回我们存储在
loc0
。
JSC还将
内联Cache嵌入到
get_by_id
,该
get_by_id
由两个未初始化的插槽组成。

现在假设我们将
getX
与
{ x: 'a' }
对象一起调用。 我们已经知道该对象具有
'x'
属性,其形状存储了
属性的偏移量和属性。 首次执行该函数时,
get_by_id
语句
get_by_id
'x'
属性,发现其值存储在偏移量0处。

内置的
get_by_id
IC
get_by_id
记住找到属性的位置的形状和偏移量。

对于后续的IC启动,您只需要比较表格即可,如果与以前相同,则只需从存储的偏移量中加载值即可。 特别是,如果JavaScript引擎看到的对象具有他早先写下的形式,那么他就不再需要询问有关这些属性的信息-而是可以完全跳过对属性信息的昂贵搜索。 这比每次花时间寻找物业要快得多。
阵列的高效存储对于数组,通常的做法是存储数组索引。 这种属性的值称为数组元素。 将数组的每个元素的属性属性存储在单独的数组中会很浪费。 相反,JavaScript引擎依赖这样的事实:默认情况下,数组中索引的属性是可写,可枚举和可配置的,并且它们还与其他命名属性分开存储数组元素。
考虑以下数组:
const array = [ '#jsconfeu', ];
引擎存储单位长度的数组,并指向包含
'length'
属性的偏移量和属性的形状。

这类似于我们之前看到的内容...但是数组元素的值存储在哪里?

每个数组都有一个单独的元素后备存储,其中包含该数组索引的所有属性值。 JavaScript引擎不需要为数组的元素存储任何属性属性,因为它们通常是可写,可枚举和可配置的。
但是,如果它们突然变得不可配置怎么办? 如果更改数组元素的属性的属性该怎么办?
上面的代码段定义了一个名为
'0'
的属性(在这种情况下,它实际上是数组的索引),它将属性值更改为非默认值。
在这种极端情况下,JavaScript引擎将元素的整个备份存储呈现为字典,该字典将数组索引映射到属性属性。

即使阵列中只有一个元素具有非默认属性,元素的备份副本的整个存储也会进入缓慢而低效的操作模式。 避免在数组索引中使用
Object.defineProperty
! (我什至不知道您为什么原则上应该使用它。这看起来很奇怪而且不合理。)
结论我们了解了JavaScript引擎如何存储对象和数组,表单和内联缓存如何帮助优化各种操作。 同样在本文中,我们想提供一些实用的JavaScript技巧,以帮助提高代码的性能:
- 始终以相同的方式初始化对象,以使它们不具有不同的形状。
- 不要弄乱数组元素的属性的属性,让它们有机会安全地存储和有效地工作。
现在,该文章可以认为是完整的。 根据既定的惯例,我们正在等待您的评论,并邀请您注册“信息系统安全”课程
的公开网络研讨会 ,该课程将于今天由著名的病毒分析师和兼职我们的老师
Alexander Kolesnikov举行 。
阅读第一部分。