javascript中的数字63385有意义吗?

javascript中的数字63385有意义吗?,javascript,node.js,performance,benchmarking,Javascript,Node.js,Performance,Benchmarking,我正在迭代大型数组和集合,同时尝试对数组和集合的性能进行基准测试 我最终发现,如果集合的长度正好是63385或更高,那么集合似乎会更快 数组似乎在任何长度下都更快 以下是我看到的: 长度63385及以上 map#Array->big x 119 ops/sec ±1.62% (76 runs sampled) map#Set->big x 349 ops/sec ±4.11% (81 runs sampled) 长度63384及以下 map#Array->medium x 2

我正在迭代大型数组和集合,同时尝试对数组和集合的性能进行基准测试

我最终发现,如果集合的长度正好是63385或更高,那么集合似乎会更快

数组似乎在任何长度下都更快

以下是我看到的:

长度63385及以上

map#Array->big x 119 ops/sec ±1.62% (76 runs sampled)
map#Set->big x 349 ops/sec ±4.11% (81 runs sampled)
长度63384及以下

map#Array->medium x 2,407 ops/sec ±0.48% (94 runs sampled)
map#Set->medium x 818 ops/sec ±0.83% (90 runs sampled)
这是我的基准代码(我知道这可能是我看到的奇怪之处的根源)

const Benchmark=require('Benchmark');
const suite=新的Benchmark.suite;
常量数组=[];
设mappedaray=[];
常量集=新集();
const mappedSet=新集合();
常数mediumArray=[];
让mediumMappedArray=[];
const mediumSet=新集合();
const mediumMappedSet=新集合();
常数max=63385;
for(设i=0;ibig',()=>{
mappedArray=array.map((val,index)=>val*2);
});
suite.add('map#Set->big',()=>{
set.forEach((val)=>mappedSet.add(val*2));
});
suite.add('map#Array->medium',()=>{
mediumMappedArray=mediumArray.map((val,index)=>val*2);
});
suite.add('map#Set->medium',()=>{
mediumSet.forEach((val)=>mediumappedset.add(val*2));
});
suite.run();

是什么导致了这种突然的变化?

您使用的是什么硬件?看起来您已经找到了二级缓存(许多x86 CPU上为256kiB)和三级缓存(3到8mib)之间的中断。使用
perf stat
查找较大阵列的LLC负载是否更高,因为负载不再在二级缓存中命中。或者使用
ocperf.py
查看二级命中/未命中事件的计数器
63384
乘以每
int
4个字节(如果JIT成功优化)非常接近256kiB。假设一些额外的二级空间被其他东西占用,或者如果数组正好填充二级缓存,则HW预取超调会导致逐出。
const Benchmark = require('benchmark');

const suite = new Benchmark.Suite;

const array = [];
let mappedArray = [];

const set = new Set();
const mappedSet = new Set();

const mediumArray = [];
let mediumMappedArray = [];
const mediumSet = new Set();
const mediumMappedSet = new Set();

const max = 63385;

for (let i = 0; i < max; i++) {
  array.push(i);
  set.add(i);

  if (i < 63385) {
    smallArray.push(i);
    smallSet.add(i);
  }
}

suite.add('map#Array->big', () => {
  mappedArray = array.map((val, index) => val * 2);
});

suite.add('map#Set->big', () => {
  set.forEach((val) => mappedSet.add(val * 2));
});

suite.add('map#Array->medium', () => {
  mediumMappedArray = mediumArray.map((val, index) => val * 2);
});

suite.add('map#Set->medium', () => {
  mediumSet.forEach((val) => mediumMappedSet.add(val * 2));
});

suite.run();