简体   繁体   English

如何在 v8 中检查 object 属性是对象内属性、快速属性还是慢速属性?

[英]How do I inspect whether a object property is a in-object property, fast property, or slow property in v8?

The post https://v8.dev/blog/fast-properties mentions there are three kinds of properties.帖子https://v8.dev/blog/fast-properties提到了三种属性。 How do I find out which one a property is?我如何找出一个属性是哪一个?

I am expecting answers with a v8 native syntax function or a devtool feature.我期待使用 v8 本机语法 function 或开发工具功能的答案。

(V8 developer here.) (这里是 V8 开发人员。)

Whether an object has dictionary-mode properties is a per-object (not per-property) decision. object 是否具有字典模式属性是每个对象(而不是每个属性)的决定。 The alternative state is to have "fast" properties, which typically means a mix of in-object and out-of-object properties.替代方案 state 具有“快速”属性,这通常意味着对象内和对象外属性的混合。

Any build of V8 running with --allow-natives-syntax can use %HasFastProperties(obj) to tell whether an object has "fast" properties (returned value is true ) or dictionary properties ( false ).任何使用--allow-natives-syntax运行的 V8 构建都可以使用%HasFastProperties(obj)来判断 object 是否具有“快速”属性(返回值为true )或字典属性( false )。

To see how many in-object properties a "fast"-mode object has, you need a Debug build, and use %DebugPrint(obj) .要查看“快速”模式 object 有多少个对象内属性,您需要调试版本,并使用%DebugPrint(obj)

To the best of my knowledge, DevTools does not expose this information.据我所知,DevTools 不会公开此信息。 (Which is fine IMHO, as you shouldn't need to care about this, aside from curiosity.) (恕我直言,这很好,因为除了好奇之外你不需要关心这个。)

Side note: I think that "fast" and "slow" are very misleading descriptions, because they sound way too much like "good case" and "bad case", when in fact they have different strengths and weaknesses.旁注:我认为“快”和“慢”是非常具有误导性的描述,因为它们听起来太像“好案例”和“坏案例”,而实际上它们具有不同的优点和缺点。 Objects that track their precise property layout using their hidden class are fast at reading/writing the values of existing properties, but exceedingly slow at adding/removing properties.使用隐藏的 class 跟踪其精确属性布局的对象在读取/写入现有属性的值时速度很快,但在添加/删除属性时非常慢。 Objects that use a dictionary for their properties are a little slower at reading/writing property values, but much faster at adding/removing properties.使用字典作为其属性的对象在读取/写入属性值时稍慢,但在添加/删除属性时要快得多。 So depending on your app's use case, you sometimes want the one and sometimes the other, and aside from pathological cases the engine is also pretty good at switching to the one or the other, and there's no object state that's clearly better than the other.因此,根据您的应用程序的用例,您有时需要一个,有时需要另一个,除了病态情况外,引擎也非常擅长切换到一个或另一个,并且没有 object state 明显优于另一个。 (And if you know you'll be adding and removing many properties, using a Map is going to give you better performance than using plain objects.) (如果您知道您将添加和删除许多属性,那么使用Map将比使用普通对象提供更好的性能。)

Here is long story short explanation for the difference between fast and slow properties.这是对快速和慢速属性之间差异的长话短说。 When an object is created in JS, a hidden class is attached to it.在JS中创建一个object时,会附加一个隐藏的class。 When a property is added to the object, “class transition” happens (the old hidden class switches to a new hidden class with the new property in it)当属性被添加到 object 时,“类转换”发生(旧的隐藏 class 切换到新的隐藏 class,其中包含新属性)

When V8 sees a class constructor function is declared, it creates a hidden class ex: C0.当 V8 看到一个 class 构造函数 function 被声明时,它创建一个隐藏的 class 例如:C0。 Now, when V8 sees on the next line a property being added, in our example: name it updates the C0 with the new property and switches from C0 to a new hidden class say C1, then it sees next property: age and switches to C2.现在,当 V8 在下一行看到一个属性被添加时,在我们的例子中:name 它用新属性更新 C0 并从 C0 切换到一个新的隐藏 class 说 C1,然后它看到下一个属性:age 并切换到 C2 .

Adding new properties dynamically to the 2 person objects in this example is not an optimized solution because the order in which the two new properties (likes and dislikes) are instantiated is different.在此示例中,向 2 人对象动态添加新属性并不是优化的解决方案,因为两个新属性(喜欢和不喜欢)的实例化顺序不同。 A different order results in the creation of two different hidden classes instead of sharing a common hidden class.不同的顺序会导致创建两个不同的隐藏类,而不是共享一个公共隐藏类 class。

So: we create C0 for the constructor function person.所以:我们为构造函数 function 人创建 C0。 It transits to C1 for name and then C2 for age.它过渡到 C1 的名字,然后是 C2 的年龄。 For person1, when it sees a property "likes" and it transits to C3a and for "dislikes" to C4a.对于 person1,当它看到一个属性时“喜欢”并转换到 C3a,“不喜欢”到 C4a。 BUT, for person2 V8 first sees the property "dislikes" being added to it and therefore instead of sharing the hidden class C3a, it creates a new hidden class C3b.但是,对于 person2,V8 首先看到属性“不喜欢”被添加到它,因此它没有共享隐藏的 class C3a,而是创建了一个新的隐藏的 class C3b。 It then creates a new hidden class for property likes say C4b.然后它为 C4b 等属性创建一个新的隐藏 class。

Since the two objects do not share the hidden classes (when they could have shared them);由于这两个对象不共享隐藏类(当它们本可以共享它们时); the access to the properties of the object is slow because V8 is now not able to make use of inline caching.访问 object 的属性很慢,因为 V8 现在无法使用内联缓存。 If the two had shared the hidden class, V8 would have used inline caching for faster access.如果两者共享隐藏的 class,V8 将使用内联缓存来加快访问速度。 So in the example below those are slow properties.所以在下面的示例中,这些是慢速属性。 Would have been fast if order was the same.如果订单相同,本来会很快。

Hope this helps a bit.希望这个对你有帮助。

 function person(name,age) { this.name = name; this.age = age; } let person1 = new person("jim", 28); let person2 = new person("jane", 27); person1.likes = "games"; person1.dislikes = "running"; person2.dislikes = "cities"; person2.likes = "nature";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM