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

预订系统资源可用性检查逻辑的优化方案咨询

预订系统资源可用性检查逻辑的优化方案咨询

嘿,我仔细看了你的资源预订系统代码和问题,确实随着资源和预订量增长,当前的写法会出现性能瓶颈,咱们一步步来优化它:

现有代码的核心问题

  • 重复过滤预订列表:每次遍历资源时都用filter去bookingList里找对应资源的预订,这会导致时间复杂度达到O(R*B)(R是资源数,B是总预订数),数据量一大就会变慢。
  • 重复日期转换:每次检查预订时都把字符串日期转成Date对象,做了很多没必要的重复工作。
  • 静态status字段误导:你现在只检查status为"Booked"的资源,但其实"Available"状态的资源可能也需要确认(比如会不会有未更新status的情况?),而且静态状态不如实际预订日期准确。

优化方案

1. 重构预订数据结构,提前分组

先把bookingList转换成按resourceId为键的对象,这样不用每次都过滤,直接通过资源ID就能拿到对应的所有预订,时间复杂度降到O(R + B)(预处理一次,后续直接查询)。

2. 提前转换日期为时间戳

把所有预订的日期和请求日期都提前转成时间戳(毫秒数),这样比较日期的时候不用重复创建Date对象,更快更高效。

3. 优化循环终止条件

一旦找到足够数量的可用资源(比如你例子里的requiredResources = 1),就立刻终止循环,不用再检查剩下的资源。

4. 去掉冗余的静态status检查

直接通过预订日期判断可用性,不管资源的静态status,避免状态不一致导致的错误。

优化后的代码示例

// 预处理:把预订列表按resourceId分组,同时转换日期为时间戳
const bookingsByResource = bookingList.reduce((acc, booking) => {
  const resourceId = booking.resourceId;
  if (!acc[resourceId]) {
    acc[resourceId] = [];
  }
  acc[resourceId].push({
    start: new Date(booking.startDate).getTime(),
    end: new Date(booking.endDate).getTime()
  });
  return acc;
}, {});

// 请求日期转时间戳
const requestStart = new Date("2025-01-15").getTime();
const requestEnd = new Date("2025-01-19").getTime();

let availableResources = [];
let newBookings = [];
const requiredResources = 1;

// 遍历资源列表,找到足够的可用资源就停止
for (const resource of resourceList) {
  if (availableResources.length >= requiredResources) break;

  const resourceBookings = bookingsByResource[resource.resourceId] || [];
  // 检查是否与任何预订重叠
  const isAvailable = resourceBookings.every(booking => {
    // 不重叠的条件:请求结束时间 <= 现有预订开始, 或者 请求开始时间 >= 现有预订结束
    return requestEnd <= booking.start || requestStart >= booking.end;
  });

  if (isAvailable) {
    availableResources.push(resource.resourceId);
    newBookings.push({
      resourceId: resource.resourceId,
      startDate: new Date(requestStart).toISOString().split("T")[0],
      endDate: new Date(requestEnd).toISOString().split("T")[0]
    });
  }
}

console.log("可用资源:", availableResources);
console.log("新增预订:", newBookings);

进一步的进阶优化

如果你的系统预订量非常大(比如上万条),可以给每个资源的预订列表按开始日期排序,然后用二分查找来快速判断是否有重叠,这样单资源的检查时间会从O(B)降到O(logB),性能提升更明显:

// 预处理时给每个资源的预订按开始时间排序
const bookingsByResource = bookingList.reduce((acc, booking) => {
  const resourceId = booking.resourceId;
  const start = new Date(booking.startDate).getTime();
  const end = new Date(booking.endDate).getTime();
  if (!acc[resourceId]) {
    acc[resourceId] = [];
  }
  acc[resourceId].push({ start, end });
  return acc;
}, {});

// 给每个资源的预订排序
Object.values(bookingsByResource).forEach(bookings => {
  bookings.sort((a, b) => a.start - b.start);
});

// 用二分查找检查重叠
function isResourceAvailable(bookings, reqStart, reqEnd) {
  let left = 0;
  let right = bookings.length - 1;
  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    const booking = bookings[mid];
    // 如果请求时间段与当前预订重叠,直接返回不可用
    if (!(reqEnd <= booking.start || reqStart >= booking.end)) {
      return false;
    }
    // 如果请求结束时间 <= 当前预订开始,去左边找更早的预订
    if (reqEnd <= booking.start) {
      right = mid - 1;
    } else {
      // 否则去右边找更晚的预订
      left = mid + 1;
    }
  }
  return true;
}

// 后续遍历资源时调用这个函数
// const isAvailable = isResourceAvailable(resourceBookings, requestStart, requestEnd);

这样处理后,即使数据量很大,系统也能保持高效运行~

备注:内容来源于stack exchange,提问作者sara ameen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:33:06