0

这会检查某些点是否在矩形内,并且无论何时运行它都会大大降低我的程序速度。我们如何改变它以提高效率?

def draw_grid(self, box):
    for element in self.map_layout.all_map_objects:
        if element not in self.build_grid and box.area.collidepoint(element.checkpoint):
            self.build_grid.append(element)
        elif not box.area.collidepoint(element.checkpoint):
            if element in self.build_grid:
                self.build_grid.remove(element)
4

3 回答 3

3

一项微不足道的更改是存储 的结果box.area.collidepoint

def draw_grid(self, box):
    for element in self.map_layout.all_map_objects:
        collidepoint = box.area.collidepoint(element.checkpoint)
        if element not in self.build_grid and collidepoint:
            self.build_grid.append(element)
        elif not collidepoint:
            if element in self.build_grid:
                self.build_grid.remove(element)

其他更改取决于您需要的数据结构。例如,self.build_grid似乎是一个list. __contains__(在运算符中)列表上的平均操作是 O(N),而如果您可以使用 a set那将是 O(1)!. 同样的事情list.remove- 在这里您可以使用一个try-except子句从紧密循环中删除一个 O(N) 操作,如果元素通常在列表中,这可能会有所帮助:

        elif not collidepoint:
            try:
                self.build_grid.remove(element)
            except ValueError:
                pass
于 2013-02-05T18:17:32.570 回答
1

您能否仅在移动元素时而不是在绘制时检查碰撞等?

此外,您可能同时调用了两次box.area.collidepoint(element.checkpoint):element in self.build_grid:一次用于 if,另一次用于 elseif。如果它的计算成本很高,你能缓存那个答案吗?

于 2013-02-05T18:16:46.847 回答
1

如果将这些点保存在某种排序的数据结构中,则无需检查每一个。按 Y 排序,在矩形的 Y 范围内查找所有内容,然后按 X 对新列表进行排序,并在矩形的 X 范围内查找所有内容。

于 2013-02-05T18:24:24.737 回答