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

为何Python中set.union()方法比集合并集运算符|性能差10倍?

集合并集方法与运算符的性能差异疑惑

我正在重新优化AdventOfCode 2023第16题的解法,原有代码如下:

from functools import cache
from helper import directions_2d
# [(0, 1), (-1, 0), (0, -1), (1, 0)]


def behavior(drt, tile):
    (row, col) = drt
    match tile:
        case "/":
            return [(-col, -row)]
        case "\\":
            return [(col, row)]
        case "|":
            if row == 0:
                return [(-1, 0), (1, 0)]
        case "-":
            if col == 0:
                return [(0, -1), (0, 1)]
    return [drt]


def run(input_data: str):
    part1 = 0
    part2 = 0
    light_map = [list(s) for s in input_data.splitlines()]
    lengths = (len(light_map), len(light_map[0]))
    starts = []
    for drt in directions_2d():
        dim = 0 if drt[0] == 0 else 1
        for i in range(lengths[dim]):
            start = [0, 0]
            start[dim] = i
            start[1 - dim] = -1 if drt[1 - dim] == 1 else lengths[1 - dim]
            starts.append([(tuple(start), drt)])

    @cache
    def run_line(row, col, drt):
        energized = set()
        (new_row, new_col) = (row, col)
        new_drt_list = [drt]
        while new_drt_list == [drt]:
            (new_row, new_col) = (new_row + drt[0], new_col + drt[1])
            if any(not 0 <= (new_row, new_col)[i] < lengths[i] for i in (0, 1)):
                new_drt_list = []
            else:
                new_drt_list = behavior(drt, light_map[new_row][new_col])
                energized.add((new_row, new_col))
        return new_row, new_col, new_drt_list, energized

    beams: list[tuple[int, int]]
    for beams in starts:
        current_i = 0
        energized = set()
        while current_i < len(beams):
            (row, col), drt = beams[current_i]
            new_row, new_col, new_drt_list, new_energized = run_line(row, col, drt)
            for new_drt in new_drt_list:
                if ((new_row, new_col), new_drt) not in beams:
                    beams.append(((new_row, new_col), new_drt))
            # 关键差异行
            energized = energized.union(new_energized)
            current_i += 1

        if beams[0] == ((0, -1), (0, 1)):
            part1 = len(energized)
        part2 = max(part2, len(energized))

    return part1, part2

将代码中的energized = energized.union(new_energized)替换为集合并集运算符写法energized |= new_energized后,程序运行时间从28-30秒大幅降至2-3秒。但我查阅各类文档与指南,均显示两者性能相近,不应存在10倍的差距。已多次运行两种版本代码确认该现象,现疑惑为何两者性能差异如此巨大?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:55:14