Chrome认为99,999与十万大不相同

当有人发布了一个与之前的,几乎相同的基准testing相冲突的jsperf基准testing时,我碰到一个非常有趣的问题。

Chrome在这两行之间做了很大的改变:

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

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

我想知道有没有人知道这里发生了什么事情!

(为了澄清,我正在寻找一些关于V8内部的低级细节,比如它们使用不同的数据结构,以及这些结构是什么)

仅仅因为这听起来很有意思,我通过V8代码库search了一个定义为100000的静态,并且我发现了这个kInitialMaxFastElementArray var ,这是随后在内置的ArrayConstructInitializeElements函数中使用的函数。 虽然我不是ac程序员,但不知道这里的细节,可以看到它使用if循环来确定它是否小于100,000,并根据这个return不同的点。

那么,在devise适合数据大小的algorithm时,总是会有一些阈值数(例如,当您将1000个项添加到列表中时,SharePoint会改变它的工作方式 )。 所以,猜测会是你已经find了实际的数字和性能的不同,因为使用不同的数据结构或algorithm。

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

Doug Lea描述了malloc如何在GNU C库中工作,比我能做得更好。 他写的。


或者,也许100000在尝试分配内存时更频繁地触发垃圾收集器,所需的空间量达到某种魔术阈值。