Javascript中的内存布局 - 面向数据与面向对象的设计

smg*_*smg 15 javascript oop memory-layout data-oriented-design

来自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];
Run Code Online (Sandbox Code Playgroud)

Chr*_*res 11

您的工作基本假设Javascript中的对象就像在C++中一样工作.他们没有.

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

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

JavaScript实现可以自由地布置内存,但是在源代码中执行的任何内容与实际在机器中实际结束的内容之间都没有对应关系.

此外,JavaScript数组是异构的,而不是同类的.也就是说,假设它是在连续的内存中布局的,你在C中的等价类型将是JSObject**,而不是int**(或浮动**或其他).JS数组是对其他地方存储的数据的引用的集合,因此即使引用位于缓存行中,您的数据也不会.

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


Ami*_*oki 5

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

首先我创造了这个测试用例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进行测试