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

如何优化未提问问题的检索逻辑?JS随机选取代码性能优化

优化随机选取未提问问题的方案

你的代码性能瓶颈在于当剩余未提问问题数量很少时,while循环会反复生成已被选中的索引,导致大量无效循环,耗时飙升。针对这个问题,以下是两种高效的优化方案:

方案一:Fisher-Yates 洗牌预处理(最优性能)

提前将问题数组打乱顺序,之后只需按顺序依次取出元素即可,完全避免重复判断和循环重试。

// 初始化时执行一次洗牌(只需要执行一次)
const questions = ['1', '2', '3', ..., 'n'];
// 复制原数组,避免修改原始数据
const shuffledQuestions = [...questions];

// Fisher-Yates 洗牌算法,原地打乱数组
for (let i = shuffledQuestions.length - 1; i > 0; i--) {
    const randomPos = Math.floor(Math.random() * (i + 1));
    // 交换当前位置和随机位置的元素
    [shuffledQuestions[i], shuffledQuestions[randomPos]] = [shuffledQuestions[randomPos], shuffledQuestions[i]];
}

// 每次获取下一个问题的函数
function getNextQuestion() {
    if (shuffledQuestions.length === 0) {
        return null; // 所有问题已提问完毕
    }
    // 从数组头部取出元素,同时移除该元素
    return shuffledQuestions.shift();
}
  • 优势:初始化洗牌的时间复杂度是O(n),之后每次取问题都是O(1)操作,性能最优,完全解决原代码的循环重试问题。

方案二:维护剩余索引的Set集合

用Set存储未被选中的问题索引,随机选取后直接从Set中删除,判断和删除操作都是O(1),不会出现循环重试。

const questions = ['1', '2', '3', ..., 'n'];
// 初始化未提问的索引集合
const remainingIndexes = new Set(Array.from({ length: questions.length }, (_, idx) => idx));

function getNextQuestion() {
    if (remainingIndexes.size === 0) {
        return null;
    }
    // 将Set转为数组,随机选取一个索引
    const randomIndex = Array.from(remainingIndexes)[Math.floor(Math.random() * remainingIndexes.size)];
    // 从集合中删除该索引,避免重复选取
    remainingIndexes.delete(randomIndex);
    return questions[randomIndex];
}
  • 优势:相比原代码,彻底消除了循环重试的情况,每次取问题的时间复杂度接近O(1),性能大幅提升;同时可以随时查看剩余问题数量,灵活性更高。

原代码的其他问题修正

  1. 变量名不一致:qAsked 和 $qAsked 混用,需保持统一;
  2. $category 未定义,原代码中 $qAsked[$category] 会报错;
  3. qCount 计算错误:应该用 questions.length 而非 questions.length-1,否则会漏掉最后一个问题的索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:21:17