You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript生成指定范围无重复随机数:1000个对象的性能最优方案

性能最优的0-4范围不重复随机数对象生成方案

需求:生成1000个对象并存储到stack数组中,每个对象包含2个0-4范围内的不重复随机数,目标是找到速度性能最优的实现方法。

以下是两种实现方案及对应的基准测试得分(得分越高,性能越好):

方案一:直接随机选取并移除元素

基准测试得分:34664

const stack = [];
for (let i = 0; i < 1000; i++) {
  const range = [0, 1, 2, 3, 4];
  let r = Math.round(Math.random() * (range.length - 1));
  let x = range[r];
  range.splice(r, 1);
  let y = range[Math.round(Math.random() * (range.length - 1))];
  stack.push({ x: x, y: y });
}

该方案每次循环创建完整的范围数组,通过Math.round()随机选取第一个元素后用splice()移除,再随机选取第二个元素。但splice()操作会修改数组并触发元素移位,累计1000次循环后会产生额外性能开销。

方案二:Fisher-Yates洗牌后取首尾元素

基准测试得分:41618

const stack = [];

for (let i = 0; i < 1000; i++) {
    let range = [0, 1, 2, 3, 4];
    shuffleArray(range);
    let x = range[0];
    let y = range[range.length - 1];
    stack.push({ x: x, y: y });
}

function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
}

该方案采用Fisher-Yates洗牌算法对范围数组进行原地打乱,直接取首尾元素作为两个不重复的随机数。Fisher-Yates洗牌仅做数组元素交换,无元素移位开销;同时Math.floor()比Math.round()更适配整数范围的随机选取(避免边界概率偏差的同时性能更稳定),因此整体性能优于方案一。

进一步优化建议

可以将基础范围数组的创建移到循环外,每次循环通过复制数组替代重新创建,减少数组初始化的重复开销:

const stack = [];
const baseRange = [0, 1, 2, 3, 4];

for (let i = 0; i < 1000; i++) {
    let range = [...baseRange];
    shuffleArray(range);
    stack.push({ x: range[0], y: range[4] });
}

function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
}

内容的提问来源于stack exchange,提问作者Tom Fan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:55:16