# UNDF: UNDF-2026-000001165 --- a/synfig-studio/src/synfigapp/actions/layerduplicate.cpp +++ b/synfig-studio/src/synfigapp/actions/layerduplicate.cpp @@ -40,6 +40,7 @@ #include #include +#include #endif @@ -112,19 +113,22 @@ get_top_parent_if_inline_canvas(Canvas::Handle canvas) /// Remove the layers that are inside an already listed group-kind layer, as they would be duplicated twice static std::list remove_layers_inside_included_pastelayers(const std::list& layer_list) { - std::vector layerpastecanvas_list; + // Build a hash set of selected paste-canvas layers for O(1) membership test. + // The original std::vector + std::find was O(P) per ancestor walk step, + // producing O(L * D * P) total where L = layers, D = nesting depth, + // P = paste-canvas count. With a hash set the inner find drops to O(1) + // and the overall complexity becomes O(L * D). + std::unordered_set layerpastecanvas_set; for (const auto& layer : layer_list) { if (dynamic_cast(layer.get())) { - layerpastecanvas_list.push_back(layer); + layerpastecanvas_set.insert(layer.get()); } } std::list clean_layer_list; for (const Layer::Handle& layer : layer_list) { bool is_inside_a_selected_pastecanvas = false; auto parent_paste_canvas = layer->get_parent_paste_canvas_layer(); while (parent_paste_canvas) { - if (std::find(layerpastecanvas_list.begin(), layerpastecanvas_list.end(), parent_paste_canvas) != layerpastecanvas_list.end()) { + if (layerpastecanvas_set.count(parent_paste_canvas.get())) { is_inside_a_selected_pastecanvas = true; break; }