diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp
index a73a4918a..26d2dbeee 100644
--- a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp
+++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp
@@ -5,7 +5,6 @@
 
 #include <stack>
 #include <functional>
-#include <unordered_set>
 #include <sstream>
 #include <queue>
 #include <functional>
@@ -522,9 +521,11 @@ static bool has_missing_twin_edge(const SkeletalTrapezoidationGraph &graph)
     return false;
 }
 
-inline static void rotate_back_skeletal_trapezoidation_graph_after_fix(SkeletalTrapezoidationGraph                       &graph,
-                                                                       const double                                       fix_angle,
-                                                                       const std::unordered_map<Point, Point, PointHash> &vertex_mapping)
+using PointMap = SkeletalTrapezoidation::PointMap;
+
+inline static void rotate_back_skeletal_trapezoidation_graph_after_fix(SkeletalTrapezoidationGraph  &graph,
+                                                                       const double                  fix_angle,
+                                                                       const PointMap               &vertex_mapping)
 {
     for (STHalfEdgeNode &node : graph.nodes) {
         // If a mapping exists between a rotated point and an original point, use this mapping. Otherwise, rotate a point in the opposite direction.
@@ -588,7 +589,7 @@ VoronoiDiagramStatus detect_voronoi_diagram_known_issues(const Geometry::Voronoi
     return VoronoiDiagramStatus::NO_ISSUE_DETECTED;
 }
 
-inline static std::pair<std::unordered_map<Point, Point, PointHash>, double> try_to_fix_degenerated_voronoi_diagram_by_rotation(
+inline static std::pair<PointMap, double> try_to_fix_degenerated_voronoi_diagram_by_rotation(
     Geometry::VoronoiDiagram                     &voronoi_diagram,
     const Polygons                               &polys,
     Polygons                                     &polys_rotated,
@@ -597,7 +598,7 @@ inline static std::pair<std::unordered_map<Point, Point, PointHash>, double> try
 {
     const Polygons                              polys_rotated_original = polys_rotated;
     double                                      fixed_by_angle         = fix_angles.front();
-    std::unordered_map<Point, Point, PointHash> vertex_mapping;
+    PointMap                                    vertex_mapping;
 
     for (const double &fix_angle : fix_angles) {
         vertex_mapping.clear();
@@ -685,7 +686,7 @@ void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys)
     const std::vector<double> fix_angles     = {PI / 6, PI / 5, PI / 7, PI / 11};
     double                    fixed_by_angle = fix_angles.front();
 
-    std::unordered_map<Point, Point, PointHash> vertex_mapping;
+    PointMap vertex_mapping;
     // polys_copy is referenced through items stored in the std::vector segments.
     Polygons                                    polys_copy = polys;
     if (status != VoronoiDiagramStatus::NO_ISSUE_DETECTED) {
@@ -813,9 +814,11 @@ process_voronoi_diagram:
             edge.from->incident_edge = &edge;
 }
 
+using NodeSet = SkeletalTrapezoidation::NodeSet;
+
 void SkeletalTrapezoidation::separatePointyQuadEndNodes()
 {
-    std::unordered_set<node_t*> visited_nodes;
+    NodeSet visited_nodes;
     for (edge_t& edge : graph.edges)
     {
         if (edge.prev) 
@@ -2285,16 +2288,18 @@ void SkeletalTrapezoidation::addToolpathSegment(const ExtrusionJunction& from, c
 
 void SkeletalTrapezoidation::connectJunctions(ptr_vector_t<LineJunctions>& edge_junctions)
 {
-    std::unordered_set<edge_t*> unprocessed_quad_starts(graph.edges.size() * 5 / 2);
+    using EdgeSet = ankerl::unordered_dense::set<edge_t*>;
+
+    EdgeSet unprocessed_quad_starts(graph.edges.size() * 5 / 2);
     for (edge_t& edge : graph.edges)
     {
         if (!edge.prev)
         {
-            unprocessed_quad_starts.insert(&edge);
+            unprocessed_quad_starts.emplace(&edge);
         }
     }
 
-    std::unordered_set<edge_t*> passed_odd_edges;
+    EdgeSet passed_odd_edges;
 
     while (!unprocessed_quad_starts.empty())
     {
diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp
index 7b8ecf834..e2a013b15 100644
--- a/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp
+++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp
@@ -7,8 +7,10 @@
 #include <boost/polygon/voronoi.hpp>
 
 #include <memory> // smart pointers
-#include <unordered_map>
 #include <utility> // pair
+
+#include <ankerl/unordered_dense.h>
+
 #include <Arachne/utils/VoronoiUtils.hpp>
 
 #include "utils/HalfEdgeGraph.hpp"
@@ -80,7 +82,9 @@ class SkeletalTrapezoidation
     const BeadingStrategy& beading_strategy;
 
 public:
-    using Segment = PolygonsSegmentIndex;
+    using Segment  = PolygonsSegmentIndex;
+    using PointMap = ankerl::unordered_dense::map<Point, Point, PointHash>;
+    using NodeSet  = ankerl::unordered_dense::set<node_t*>;
 
     /*!
      * Construct a new trapezoidation problem to solve.
@@ -164,8 +168,8 @@ protected:
      * mapping each voronoi VD edge to the corresponding halfedge HE edge
      * In case the result segment is discretized, we map the VD edge to the *last* HE edge
      */
-    std::unordered_map<vd_t::edge_type*, edge_t*> vd_edge_to_he_edge;
-    std::unordered_map<vd_t::vertex_type*, node_t*> vd_node_to_he_node;
+    ankerl::unordered_dense::map<vd_t::edge_type*, edge_t*> vd_edge_to_he_edge;
+    ankerl::unordered_dense::map<vd_t::vertex_type*, node_t*> vd_node_to_he_node;
     node_t& makeNode(vd_t::vertex_type& vd_node, Point p); //!< Get the node which the VD node maps to, or create a new mapping if there wasn't any yet.
 
     /*!
diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidationGraph.cpp b/src/libslic3r/Arachne/SkeletalTrapezoidationGraph.cpp
index 4ef96eda1..4629396e8 100644
--- a/src/libslic3r/Arachne/SkeletalTrapezoidationGraph.cpp
+++ b/src/libslic3r/Arachne/SkeletalTrapezoidationGraph.cpp
@@ -2,7 +2,8 @@
 //CuraEngine is released under the terms of the AGPLv3 or higher.
 
 #include "SkeletalTrapezoidationGraph.hpp"
-#include <unordered_map>
+
+#include <ankerl/unordered_dense.h>
 
 #include <boost/log/trivial.hpp>
 
@@ -180,8 +181,8 @@ bool STHalfEdgeNode::isLocalMaximum(bool strict) const
 
 void SkeletalTrapezoidationGraph::collapseSmallEdges(coord_t snap_dist)
 {
-    std::unordered_map<edge_t*, std::list<edge_t>::iterator> edge_locator;
-    std::unordered_map<node_t*, std::list<node_t>::iterator> node_locator;
+    ankerl::unordered_dense::map<edge_t*, Edges::iterator> edge_locator;
+    ankerl::unordered_dense::map<node_t*, Nodes::iterator> node_locator;
     
     for (auto edge_it = edges.begin(); edge_it != edges.end(); ++edge_it)
     {
@@ -193,7 +194,7 @@ void SkeletalTrapezoidationGraph::collapseSmallEdges(coord_t snap_dist)
         node_locator.emplace(&*node_it, node_it);
     }
     
-    auto safelyRemoveEdge = [this, &edge_locator](edge_t* to_be_removed, std::list<edge_t>::iterator& current_edge_it, bool& edge_it_is_updated)
+    auto safelyRemoveEdge = [this, &edge_locator](edge_t* to_be_removed, Edges::iterator& current_edge_it, bool& edge_it_is_updated)
     {
         if (current_edge_it != edges.end()
             && to_be_removed == &*current_edge_it)
diff --git a/src/libslic3r/Arachne/WallToolPaths.cpp b/src/libslic3r/Arachne/WallToolPaths.cpp
index 1c69fa9ac..fce69d5e4 100644
--- a/src/libslic3r/Arachne/WallToolPaths.cpp
+++ b/src/libslic3r/Arachne/WallToolPaths.cpp
@@ -2,7 +2,6 @@
 // CuraEngine is released under the terms of the AGPLv3 or higher.
 
 #include <algorithm> //For std::partition_copy and std::min_element.
-#include <unordered_set>
 
 #include "WallToolPaths.hpp"
 
@@ -767,9 +766,9 @@ bool WallToolPaths::removeEmptyToolPaths(std::vector<VariableWidthLines> &toolpa
      *
      * \param outer_to_inner Whether the wall polygons with a lower inset_idx should go before those with a higher one.
  */
-std::unordered_set<std::pair<const ExtrusionLine *, const ExtrusionLine *>, boost::hash<std::pair<const ExtrusionLine *, const ExtrusionLine *>>> WallToolPaths::getRegionOrder(const std::vector<ExtrusionLine *> &input, const bool outer_to_inner)
+WallToolPaths::ExtrusionLineSet WallToolPaths::getRegionOrder(const std::vector<ExtrusionLine *> &input, const bool outer_to_inner)
 {
-    std::unordered_set<std::pair<const ExtrusionLine *, const ExtrusionLine *>, boost::hash<std::pair<const ExtrusionLine *, const ExtrusionLine *>>> order_requirements;
+    ExtrusionLineSet order_requirements;
 
     // We build a grid where we map toolpath vertex locations to toolpaths,
     // so that we can easily find which two toolpaths are next to each other,
diff --git a/src/libslic3r/Arachne/WallToolPaths.hpp b/src/libslic3r/Arachne/WallToolPaths.hpp
index b0bed1241..44f3affb6 100644
--- a/src/libslic3r/Arachne/WallToolPaths.hpp
+++ b/src/libslic3r/Arachne/WallToolPaths.hpp
@@ -5,7 +5,8 @@
 #define CURAENGINE_WALLTOOLPATHS_H
 
 #include <memory>
-#include <unordered_set>
+
+#include <ankerl/unordered_dense.h>
 
 #include "BeadingStrategy/BeadingStrategyFactory.hpp"
 #include "utils/ExtrusionLine.hpp"
@@ -73,6 +74,7 @@ public:
      */
     static bool removeEmptyToolPaths(std::vector<VariableWidthLines> &toolpaths);
 
+    using ExtrusionLineSet = ankerl::unordered_dense::set<std::pair<const ExtrusionLine *, const ExtrusionLine *>, boost::hash<std::pair<const ExtrusionLine *, const ExtrusionLine *>>>;
     /*!
      * Get the order constraints of the insets when printing walls per region / hole.
      * Each returned pair consists of adjacent wall lines where the left has an inset_idx one lower than the right.
@@ -81,7 +83,7 @@ public:
      *
      * \param outer_to_inner Whether the wall polygons with a lower inset_idx should go before those with a higher one.
      */
-    static std::unordered_set<std::pair<const ExtrusionLine *, const ExtrusionLine *>, boost::hash<std::pair<const ExtrusionLine *, const ExtrusionLine *>>> getRegionOrder(const std::vector<ExtrusionLine *> &input, bool outer_to_inner);
+    static ExtrusionLineSet getRegionOrder(const std::vector<ExtrusionLine *> &input, bool outer_to_inner);
 
 protected:
     /*!
diff --git a/src/libslic3r/Arachne/utils/HalfEdgeGraph.hpp b/src/libslic3r/Arachne/utils/HalfEdgeGraph.hpp
index 99efff6a0..17b06f2be 100644
--- a/src/libslic3r/Arachne/utils/HalfEdgeGraph.hpp
+++ b/src/libslic3r/Arachne/utils/HalfEdgeGraph.hpp
@@ -21,8 +21,10 @@ class HalfEdgeGraph
 public:
     using edge_t = derived_edge_t;
     using node_t = derived_node_t;
-    std::list<edge_t> edges;
-    std::list<node_t> nodes;
+    using Edges = std::list<edge_t>;
+    using Nodes = std::list<node_t>;
+    Edges edges;
+    Nodes nodes;
 };
 
 } // namespace Slic3r::Arachne
diff --git a/src/libslic3r/Arachne/utils/PolylineStitcher.hpp b/src/libslic3r/Arachne/utils/PolylineStitcher.hpp
index 2ab770a3e..113761ce1 100644
--- a/src/libslic3r/Arachne/utils/PolylineStitcher.hpp
+++ b/src/libslic3r/Arachne/utils/PolylineStitcher.hpp
@@ -7,7 +7,6 @@
 #include "SparsePointGrid.hpp"
 #include "PolygonsPointIndex.hpp"
 #include "../../Polygon.hpp"
-#include <unordered_set>
 #include <cassert>
 
 namespace Slic3r::Arachne
diff --git a/src/libslic3r/Arachne/utils/SparseGrid.hpp b/src/libslic3r/Arachne/utils/SparseGrid.hpp
index be461d424..45876fb9a 100644
--- a/src/libslic3r/Arachne/utils/SparseGrid.hpp
+++ b/src/libslic3r/Arachne/utils/SparseGrid.hpp
@@ -6,7 +6,6 @@
 #define UTILS_SPARSE_GRID_H
 
 #include <cassert>
-#include <unordered_map>
 #include <vector>
 #include <functional>
 
diff --git a/src/libslic3r/Arachne/utils/SparseLineGrid.hpp b/src/libslic3r/Arachne/utils/SparseLineGrid.hpp
index a9b536869..0b38988f9 100644
--- a/src/libslic3r/Arachne/utils/SparseLineGrid.hpp
+++ b/src/libslic3r/Arachne/utils/SparseLineGrid.hpp
@@ -6,7 +6,6 @@
 #define UTILS_SPARSE_LINE_GRID_H
 
 #include <cassert>
-#include <unordered_map>
 #include <vector>
 #include <functional>
 
diff --git a/src/libslic3r/Arachne/utils/SparsePointGrid.hpp b/src/libslic3r/Arachne/utils/SparsePointGrid.hpp
index 31c196535..7bb51d703 100644
--- a/src/libslic3r/Arachne/utils/SparsePointGrid.hpp
+++ b/src/libslic3r/Arachne/utils/SparsePointGrid.hpp
@@ -6,7 +6,6 @@
 #define UTILS_SPARSE_POINT_GRID_H
 
 #include <cassert>
-#include <unordered_map>
 #include <vector>
 
 #include "SparseGrid.hpp"
diff --git a/src/libslic3r/Arachne/utils/SquareGrid.hpp b/src/libslic3r/Arachne/utils/SquareGrid.hpp
index c59c3ee1b..5787e3bf1 100644
--- a/src/libslic3r/Arachne/utils/SquareGrid.hpp
+++ b/src/libslic3r/Arachne/utils/SquareGrid.hpp
@@ -7,7 +7,6 @@
 #include "../../Point.hpp"
 
 #include <cassert>
-#include <unordered_map>
 #include <vector>
 #include <functional>
 
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index 89add5978..1a487cba8 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -39,11 +39,11 @@
 #include <ostream>
 #include <stack>
 #include <string>
-#include <unordered_map>
-#include <unordered_set>
 #include <utility>
 #include <vector>
 
+#include <ankerl/unordered_dense.h>
+
 // #define ARACHNE_DEBUG
 
 #ifdef ARACHNE_DEBUG
@@ -569,7 +569,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
                         size_t occurrence  = 0;
                         bool   is_overhang = false;
                     };
-                    std::unordered_map<Point, PointInfo, PointHash> point_occurrence;
+                    ankerl::unordered_dense::map<Point, PointInfo, PointHash> point_occurrence;
                     for (const ExtrusionPath &path : paths) {
                         ++point_occurrence[path.polyline.first_point()].occurrence;
                         ++point_occurrence[path.polyline.last_point()].occurrence;
@@ -681,7 +681,7 @@ Polylines reconnect_polylines(const Polylines &polylines, double limit_distance)
     if (polylines.empty())
         return polylines;
 
-    std::unordered_map<size_t, Polyline> connected;
+    ankerl::unordered_dense::map<size_t, Polyline> connected;
     connected.reserve(polylines.size());
     for (size_t i = 0; i < polylines.size(); i++) {
         if (!polylines[i].empty()) {
@@ -731,7 +731,7 @@ ExtrusionPaths sort_extra_perimeters(ExtrusionPaths extra_perims, int index_of_f
 {
     if (extra_perims.empty()) return {};
 
-    std::vector<std::unordered_set<size_t>> dependencies(extra_perims.size());
+    std::vector<ankerl::unordered_dense::set<size_t>> dependencies(extra_perims.size());
     for (size_t path_idx = 0; path_idx < extra_perims.size(); path_idx++) {
         for (size_t prev_path_idx = 0; prev_path_idx < path_idx; prev_path_idx++) {
             if (paths_touch(extra_perims[path_idx], extra_perims[prev_path_idx], extrusion_spacing * 1.5f)) {
@@ -1153,11 +1153,11 @@ void PerimeterGenerator::process_arachne(
     // Find topological order with constraints from extrusions_constrains.
     std::vector<size_t>              blocked(all_extrusions.size(), 0); // Value indicating how many extrusions it is blocking (preceding extrusions) an extrusion.
     std::vector<std::vector<size_t>> blocking(all_extrusions.size());   // Each extrusion contains a vector of extrusions that are blocked by this extrusion.
-    std::unordered_map<const Arachne::ExtrusionLine *, size_t> map_extrusion_to_idx;
+    ankerl::unordered_dense::map<const Arachne::ExtrusionLine *, size_t> map_extrusion_to_idx;
     for (size_t idx = 0; idx < all_extrusions.size(); idx++)
         map_extrusion_to_idx.emplace(all_extrusions[idx], idx);
 
-    auto extrusions_constrains = Arachne::WallToolPaths::getRegionOrder(all_extrusions, params.config.external_perimeters_first);
+    Arachne::WallToolPaths::ExtrusionLineSet extrusions_constrains = Arachne::WallToolPaths::getRegionOrder(all_extrusions, params.config.external_perimeters_first);
     for (auto [before, after] : extrusions_constrains) {
         auto after_it = map_extrusion_to_idx.find(after);
         ++blocked[after_it->second];
diff --git a/src/libslic3r/ShortEdgeCollapse.cpp b/src/libslic3r/ShortEdgeCollapse.cpp
index 0c940cb47..c8e4eb97e 100644
--- a/src/libslic3r/ShortEdgeCollapse.cpp
+++ b/src/libslic3r/ShortEdgeCollapse.cpp
@@ -6,6 +6,8 @@
 #include <random>
 #include <algorithm>
 
+#include <ankerl/unordered_dense.h>
+
 namespace Slic3r {
 
 void its_short_edge_collpase(indexed_triangle_set &mesh, size_t target_triangle_count) {
@@ -155,7 +157,7 @@ void its_short_edge_collpase(indexed_triangle_set &mesh, size_t target_triangle_
     }
 
     //Extract the result mesh
-    std::unordered_map<size_t, size_t> final_vertices_mapping;
+    ankerl::unordered_dense::map<size_t, size_t> final_vertices_mapping;
     std::vector<Vec3f> final_vertices;
     std::vector<Vec3i> final_indices;
     final_indices.reserve(face_indices.size());