当有人发布了一个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内部的一些低级细节,例如它使用不同的数据结构,一个与另一个以及这些结构是什么)
答案 0 :(得分:53)
仅仅因为这听起来非常有趣,我在V8代码库中搜索了一个定义为100000的静态,然后我找到this kInitialMaxFastElementArray
var,后来在builtin ArrayConstructInitializeElements
function函数中使用了{{3}}。虽然我不是程序员而且不知道这里的细节,你可以看到它使用if
循环来确定它是否小于100,000,并且return
在不同的点基于在那。
答案 1 :(得分:10)
当您设计适应数据大小的算法时,总会有一些阈值数(例如SharePoint changes the way it works when you add 1000 items to a list)。因此,猜测是你找到了实际的数字并且性能不同,因为使用了不同的数据结构或算法。
答案 2 :(得分:4)
我不知道你正在使用什么操作系统,但如果这是Linux,我怀疑Chrome(即malloc
)是从程序管理的堆中分配内存(使用sbrk
系统调用,并且空闲列表由C标准库管理),但是当达到特定大小阈值时,它会切换到使用mmap
来请求内核分配大块内存,不要干扰sbrk
- 托管堆。
Doug Lea描述了malloc
如何在GNU C库中运行,比我更好。他写了。
或许100000点击某种魔法阈值,以便在尝试分配内存时更频繁地触发垃圾收集器所需的空间量。