【问题标题】:Memory layout in Javascript - data-oriented vs object-oriented design [closed]Javascript中的内存布局-面向数据与面向对象的设计[关闭]
【发布时间】:2014-09-22 08:31:51
【问题描述】:

来自 C/C++ 背景,对象的内存布局对于减少缓存未命中至关重要,尤其是在控制台上工作时。面向数据的设计通常比面向对象的设计更受青睐,以帮助保持相关对象在内存中彼此靠近(尤其是在性能关键区域)。

最近,我一直在做一些 Javascript 开发,我想知道 Javascript 社区内的普遍共识是什么。

由于我在 Javascript 方面的经验有限,在进行分析时看到完全出乎意料的结果常常让我感到惊讶。 Javascript对象/结构的内部内存布局和实现因浏览器而异,我想知道是否值得尝试优化。

我在 jsPerf 上创建了一个简单的测试用例 (http://jsperf.com/object-vs-data) 来比较两种方法的性能,虽然它在 Chrome 上显示了性能提升,但在 Safari 上没有明显的加速。

在 Javascript 中,我是否应该关注对象的内存布局?还是更像是“以一种方式实现,然后在需要时进行优化”类型的东西?

第二个选项似乎有点浪费(就开发时间而言),尤其是如果有一些好的指导方针可以遵循的话。

谢谢~

补充信息:这基本上就是我在 Javascript 中实现这两种方法的方式。上面的jsPerf测试用例就是这样实现的。

var objectOriented = [
    { foo: 1, bar: 2 },
    { foo: 3, bar: 4 }
];

var dataOriented = {
    foos: [1, 3],
    bars: [2, 4]
};

// Object-oriented access:
var a = objectOriented[0].bar;

// Data-oriented access:
var b = dataOriented.bars[0];

【问题讨论】:

  • 完美的问题... +1,但我担心这主要是基于意见。
  • 我认为如果 foos 和 bar 的连接比 bar 与其他 bar 以及 foos 与其他 foo 的连接更多,我会推荐第一种方法。而且节省的时间也很少。这个特定的功能必须运行至少 600,000,000 次才能弥补你 5 分钟的思考时间。
  • JS 是一种非常高级的语言,所以我很确定您不必担心数据结构的内存布局。您如何构建对象也几乎取决于您,最好为您的数据考虑一个更具体的用例以找到一个好的表示。
  • 我不知道点击 [Run Test] 按钮有什么作用,所以如果这搞砸了,我为 firefox 测试道歉:(
  • 除非您使用类型化数组(并通过DataView 左右访问它们),否则您几乎无法管理内存布局。此外,一切都是对象,因此您无法真正创建无 OOP 的纯数据对象。

标签: javascript oop memory-layout data-oriented-design


【解决方案1】:

您的工作基于一个基本假设,即 Javascript 中的对象与 C++ 中的对象一样工作。他们没有。

在 C++ 中,类型的主要目的是充当一块内存的“镜头”。类布局以明确定义的方式直接定义对象描述的内存内容。 C/C++ 数组特别需要同质类型的线性、连续布局。

在 JavaScript 中,对象是名称/值对的集合。数组只是一个具有特殊“长度”属性的对象。请注意,这里没有内存布局的描述或定义。没有什么能阻止 Javascript 解释器将数组实现为哈希表而不是线性内存块;事实上,我确信它们就是 JS 实现。

JavaScript 实现可以随意分配内存,并且您在源代码中所做的任何事情与机器中实际完成的事情之间没有对应关系。

此外,JavaScript 数组是异构的,而不是同质的。也就是说,假设它被布置在连续的内存中,那么您在 C 中的等效类型将是 JSObject **,而不是 int **(或 float ** 或其他)。 JS 数组是对存储在其他地方的数据的引用的集合,因此即使引用在您的缓存行中,您的数据也不会。

所以,总而言之——这种想法只会给你带来痛苦。 JavaScript 是一种比 C++ 高级得多的语言,其中一部分原因是放弃了您习惯的控制。如果可能的话,这种低级优化将由解释器完成。专注于使用自然表达您的解决方案的高效算法编写代码;这已经够难了。 :-)

【讨论】:

    【解决方案2】:

    好的。摆弄了一些数字和测试用例..

    首先我创建了这个测试用例http://jsperf.com/object-vs-array-creation-for-so 在这种情况下,创建Object更快然后创建Array

    其次我创建了这个测试用例http://jsperf.com/accessing-speed 在这一点上,他们之间几乎没有任何区别..

    所以,我从这个配置文件中推断出,如果项目非常庞大,使用对象多于数组会更快。因为从第一种情况来看,很明显对象创建速度更快比创建数组。

    但是..

    Javascript 是一种高度发达的高性能语言,您不必担心这种微优化。您应该只关注语义。你应该选择最能描述你意图的结构。

    在 Windows NT 6.3 上的 Chrome 36.0.1985.125 中测试

    【讨论】:

    • 有趣的是,Firefox 创建ObjectArray 的结果相同。
    • 对于登陆这里的新用户:他们现在并驾齐驱。只需使用在您的上下文中有意义的任何一个,它对性能无关紧要。
    • @JoshPowlison - 这里的测试都没有真正测试问题。对于大多数 Web 开发人员来说,数组不太可能大到足以证明内存布局优化的合理性。更好地看待计算和网络。如果我们现在也需要控制内存,我们可以将 C++ 编译为 Web 程序集或 asm.js。
    猜你喜欢
    • 1970-01-01
    • 2019-06-28
    • 2014-06-19
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 2013-02-23
    相关资源
    最近更新 更多