Chrome认为99999和100000相差很大

38

我最近遇到了一个非常有趣的问题,当有人发布了一个 jsperf 基准测试与我之前运行的一个几乎相同的基准测试发生了冲突。

在这两行代码中,Chrome的处理方式 截然不同

new Array(99999);  // jsperf ~50,000 ops/sec
new Array(100000); // jsperf ~1,700,000 ops/sec

基准测试:http://jsperf.com/newarrayassign/2

我想知道这里到底发生了什么!

(澄清一下,我正在寻找有关V8内部的一些低级细节,例如它在一个中使用不同的数据结构与另一个中使用什么样的结构)


9
如果您将测试顺序颠倒,会发生什么? - Cole
也许是因为它是一个更大的数字,并且它处理六位数的方式不同? - beardhatcode
如果是这样的话,那么开关将会在65,53616,777,216或其他2的幂处。 - user578895
应该认为这样的门槛会有更加规范的大小,而不是100000,这相当丑陋。最好是65536、131072或98304! - leftaroundabout
@leftaroundabout - 98,304?真的吗? - user578895
@leftaroundabout,是的我知道,但为什么? - user578895
3个回答

52

10
我理解的是,Chrome在所有小于100,000的数组中实际上是进行指针内存分配,而在大于或等于100,000的数组中则没有进行任何分配。这在基准测试中是有道理的,因为声明只需速度更快,但是使用该数组比使用99,999数组更慢。 - user578895
@CodyGray - 哇哦,这个问题已经十年了,最佳实践当时还没有完全建立起来。我花了几分钟时间更新了答案,指向了Github,希望它更加稳定。我不知道我上面的“if”循环是什么意思...可能应该说“在if语句中的逻辑”。 - eykanal
我认为我们在10年前就已经有了关于“仅链接”答案的相同规则,因为即使在那时,“链接腐败”的问题也是众所周知的。无论如何,感谢您在此方面付出了一些努力。显然,多年来它对其他人有用,因此可以合理地假设一旦更新,它将继续有用。我已删除我的原始评论作为过时的评论,还删除了其他几个评论,称链接已失效。 - Cody Gray

10

3
我不知道你使用的操作系统是什么,但如果是Linux,我会怀疑Chrome(即malloc)正在从程序管理的堆中分配内存(使用sbrk系统调用确定大小,并且空闲列表由C标准库管理),但当达到一定大小阈值时,它会切换到使用mmap来请求内核分配大块内存,这不会干扰sbrk管理的堆。

Doug Lea描述了GNU C库中malloc的工作原理,比我能做得更好。他写了这个。


或者100000达到了某种需要的空间的魔法门槛,这会在尝试分配内存时更频繁地触发垃圾回收器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接