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

如何提升时间片重叠检测循环的执行性能?

时间片重叠检测性能优化问题

我正在编写一个检测时间片是否重叠的脚本,现有处理函数intersection_checker如下:

def intersection_checker(foo, bar):
    if foo == bar:
       return True
    if foo[0] == bar[1] or foo[1] == bar[0]:
       return True
    if bar[0] < (foo[0] or foo[1]) < bar[1]:
       return True
    if foo[0] < (bar[0] or bar[1]) < foo[1]:
       return True
    return False

其中foo是包含两个datetime.time()对象的元组:

foo = (datetime.strptime('06:30:00','%H:%M:%S').time(), datetime.strptime('08:15:00','%H:%M:%S').time())

bar是包含200k+同类元组的集合。当前调用该函数的代码如下:

...
if len(bar) > 1 and True in set(map(intersection_checker, repeat(foo), bar)):
...

代码可正常运行,但处理大数据量时性能极差。我尝试过用for循环遍历调用函数,但效果不如内置map。希望找到更高效的大数据处理方式,或优化重叠检测逻辑,且只需找到第一个返回True的情况即可,无需遍历全部bar元素。


优化方案

1. 修复并简化重叠检测逻辑

原函数中(foo[0] or foo[1])的写法存在逻辑错误,or会返回第一个为真的对象,而非用于区间判断的有效值。时间片重叠的核心判断逻辑可以简化为:两个区间不重叠的唯一情况是一个完全在另一个的左侧,取反即可得到重叠条件。同时增加对时间片起始/结束顺序的修正,避免传入顺序错误导致的误判。

优化后的函数:

def intersection_checker(foo, bar):
    # 确保时间片的起始<=结束
    foo_start, foo_end = sorted(foo)
    bar_start, bar_end = sorted(bar)
    # 不重叠的情况取反,即为重叠
    return not (foo_end <= bar_start or bar_end <= foo_start)

2. 高效遍历:短路求值终止迭代

原代码用set(map(...))会遍历所有元素并生成集合,完全浪费性能——我们只需要找到第一个匹配项就可以停止遍历。使用any()函数配合迭代器/生成器表达式,会在遇到第一个True时立即终止迭代,性能提升显著:

方式一:生成器表达式

if len(bar) > 1 and any(intersection_checker(foo, b) for b in bar):
    # 处理重叠逻辑
    ...

方式二:map配合any()

from itertools import repeat

if len(bar) > 1 and any(map(intersection_checker, repeat(foo), bar)):
    # 处理重叠逻辑
    ...

3. 进阶优化:预排序+二分查找(针对复用场景)

如果bar集合固定不变,可以先对其按时间片起始时间排序,再用二分查找快速缩小需要检查的元素范围,进一步降低查询耗时:

import bisect

# 预排序bar(仅需执行一次)
sorted_bar = sorted(bar, key=lambda x: x[0])

def has_overlap(foo, sorted_intervals):
    foo_start, foo_end = sorted(foo)
    # 用二分查找定位第一个起始时间大于foo_end的区间
    idx = bisect.bisect_right(sorted_intervals, (foo_end,), key=lambda x: x[0])
    # 仅检查前idx个区间,后续区间不可能重叠
    for interval in sorted_intervals[:idx]:
        bar_start, bar_end = sorted(interval)
        if not (foo_end <= bar_start or bar_end <= foo_start):
            return True
    return False

# 调用
if len(sorted_bar) > 1 and has_overlap(foo, sorted_bar):
    # 处理重叠逻辑
    ...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:15:13