【问题标题】:What is this generated code supposed (intended) to do?这个生成的代码应该(打算)做什么?
【发布时间】:2013-10-10 14:30:40
【问题描述】:

我在一个自动生成的 javascript 文件中看到了这个:

function map(x){
    x={x:x};
    delete x.x;
    return x
}

我的结论是用来创建对象的,但是为什么要这样创建呢?它是一种模式吗?

更新

更多信息,创建此代码的工具是来自 Google 的 dart2js,代码在此上下文中使用:

(function (reflectionData) {
  function map(x){x={x:x};delete x.x;return x}
  if (!init.libraries) init.libraries = [];
  if (!init.mangledNames) init.mangledNames = map();
  if (!init.mangledGlobalNames) init.mangledGlobalNames = map();
  if (!init.statics) init.statics = map();
  if (!init.interfaces) init.interfaces = map();

【问题讨论】:

  • 我做了,它创建了一个空对象。
  • 这是从哪里来的?它看起来更像是一个代码拼图,而不是你在真实库中实际看到的东西——就像它在 javascript 测验或其他东西中一样。
  • 在我看来真的很愚蠢。
  • 鉴于无法回答这个问题(由于没有足够的上下文 - 并看到下面的负面投票结果),我认为应该关闭。
  • 在 dart 源代码中,有一条评论说这种技术用于 v8 性能原因:github.com/dart-lang/bleeding_edge/blob/…

标签: javascript javascript-objects


【解决方案1】:

在 dart 源代码中,有一条评论说这种技术用于 v8 性能原因:

// [map] returns an object literal that V8 shouldn't try to optimize with a
// hidden class. This prevents a potential performance problem where V8 tries
// to build a hidden class for an object used as a hashMap.

https://github.com/dart-lang/bleeding_edge/blob/4dde22bc006605fc168cefcc0807c43354463b6e/dart/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart#L17-L19

这里的map这个词指的是associative array

【讨论】:

    【解决方案2】:

    我不久前读过一篇关于这个的文章,如果你 delete 来自对象的某些东西,V8 会将对象置于 字典模式慢速模式,然后将属性存储在“哈希表”中。

    V8 可以很好地处理这样的细微差异,但是如果您的代码以不特定的顺序将各种随机属性分配给来自同一个构造函数的对象,或者如果您删除属性,V8 会将对象放入字典模式,其中属性存储在哈希表中。这可以防止分配的地图数量过多。

    这是http://www.jayconrod.com/posts/52/a-tour-of-v8-object-representation 的文章,它在其中解释了它以及其他内容。

    我可能错了,但我认为这是用于大型(在大小和寿命方面)对象以提高性能并减少内存泄漏的机会。

    这是同一个主题

    Does using delete keyword effect v8 optimizations of an object?

    【讨论】:

      【解决方案3】:

      map 函数的目的是创建一个关联映射对象,其属性集可以快速更改。

      很自然的问题出现了:默认情况下不是所有的 JavaScript 对象都已经映射了吗?是的,它们是! EMCAScript 规范允许对象随时添加或删除属性,从而允许它们充当关联映射。

      但是,可惜的是,负责实现 JavaScript 执行环境的低级语言(可能是 C++)并不那么容易上手。特别是,V8 使用了一个名为 hidden classes 的概念,向 JavaScript 对象添加属性将导致创建新的 C++ 类。 V8 这样做是为了优化,因为它假设您的代码将重复使用一小组对象类型。

      例如,您有一个具有xydxdy 属性的Bullet 类型。实际上,这些类型是固定的;您不太可能会突然将新属性添加到 Bullet 对象。隐藏类优化意味着使用一组固定的对象类型运行速度非常快,但这也意味着,有时,为 JS 对象添加新属性的实际成本可能相当高,因为它会提示创建一个具有新属性的新 C++ 类。

      通过在对象x 上引入delete 操作,您向V8 引擎发出信号,该对象x 将不会从隐藏类优化中受益。隐藏类背后的想法是您的对象通常不会更改它们的属性集(除了在构造时添加新属性)。通过执行delete,您明确表示该对象将以使隐藏类完全无用的方式更改其属性集。对于这个对象,创建隐藏类的成本远远超过收益。

      因此,map 返回的对象将被排除在 V8 隐藏类优化之外,从而可以更快地添加和删除任意属性。

      【讨论】:

      • 非常有趣的解释,谢谢:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-30
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-07
      • 1970-01-01
      相关资源
      最近更新 更多