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

Qt结合OpenGL场景下如何高效删除大量指定图形?

问题根因分析

你的代码耗时核心来自两个O(n)操作嵌套,最终产生了O(n²)的时间复杂度,百万级数据下运算量指数级上涨:

  • alldrawerlist.indexOf(p) 是线性查找逻辑,每次执行都需要遍历整个alldrawerlist才能匹配到对应指针的索引
  • alldrawerlist.removeAt(index) 删除非末尾元素时,需要将索引后的所有元素整体向前移动,也是O(n)时间开销

两类操作嵌套在百万次循环中,嵌入式设备性能不足以支撑如此大的运算量,必然出现卡顿。

优化方案

1. 单次遍历过滤+批量删除,时间复杂度降至O(n)

先将待删除的指针存入QSet实现O(1)存在性判断,随后仅遍历一次全量Drawable列表,过滤出需要保留的对象重建全量列表,同时批量释放待删除对象,完全避免重复查找和列表元素移动的开销,优化后代码如下:

void deleteDrawable()
{
    if(need_to_delete_drawerlist.isEmpty()) return;
    // 转存为集合实现O(1)查找
    QSet<Drawable*> delete_set(need_to_delete_drawerlist.begin(), need_to_delete_drawerlist.end());
    QList<Drawable*> retained_list;
    // 预分配内存,避免动态扩容开销
    retained_list.reserve(alldrawerlist.size() - need_to_delete_drawerlist.size());

    for (auto drawable : alldrawerlist) {
        if (delete_set.contains(drawable)) {
            delete drawable;
        } else {
            retained_list.append(drawable);
        }
    }
    // 替换原全量列表
    alldrawerlist.swap(retained_list);
    need_to_delete_drawerlist.clear();
}

2. 新增删除标记简化逻辑

如果业务允许,可以直接在Drawable类中新增删除标记位,不需要单独维护need_to_delete_drawerlist,需要删除线条时直接给对应对象打标记即可,进一步降低维护开销:

class Drawable : protected QOpenGLExtraFunctions
{
public:
    bool is_to_delete = false;
    // 其余原有逻辑
    ......
}

删除函数可简化为:

void deleteDrawable()
{
    QList<Drawable*> retained_list;
    retained_list.reserve(alldrawerlist.size());
    for (auto drawable : alldrawerlist) {
        if (drawable->is_to_delete) {
            delete drawable;
        } else {
            retained_list.append(drawable);
        }
    }
    alldrawerlist.swap(retained_list);
}

3. 额外性能优化点

  • 替换QList为QVector:QVector采用连续内存存储,遍历效率远高于QList,百万级元素下性能提升尤为明显
  • 批量释放OpenGL资源:如果Drawable持有VBO、VAO等OpenGL资源,不要在析构函数中单个释放,可以将待释放的资源ID攒齐后批量调用glDeleteBuffers等接口,OpenGL批量操作的性能远优于多次单次操作
  • 分帧分批删除:如果单次需要删除的元素量极大,可以将删除操作分散到多个渲染帧的空闲间隙执行,每帧仅删除固定数量(例如1000个)的对象,避免阻塞渲染主线程导致卡顿
  • 引入对象池复用Drawable:避免频繁new/delete小对象带来的堆分配开销和内存碎片,嵌入式设备上内存碎片会进一步拖慢后续内存操作速度,对象池可大幅降低这类开销

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 02:57:03