From 5ed8f5ef258898a4006677bab8a3f2e412adedec Mon Sep 17 00:00:00 2001 From: Grant Harkness <64664463+grant0013@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:51:27 +0100 Subject: [PATCH] perf(GCodeProcessor): stop recompiling std::regex on every g-code line (up to 2.9x faster slicing) (#14166) perf(GCodeProcessor): stop recompiling std::regex on every g-code line process_SET_VELOCITY_LIMIT() constructed three std::regex objects from scratch on every call, and Klipper-flavor g-code contains SET_VELOCITY_LIMIT on a large share of lines (8,834 of 103,549 lines for a single 3DBenchy sliced for a Creality K2). perf attributes 6.4% of the whole slicing run to this one function, almost all of it regex compilation and the allocator traffic it generates. process_SET_PRESSURE_ADVANCE() and the External_Purge_Tag handler had the same per-call construction. Hoist all five patterns to function-local static const std::regex so they compile once. Generated g-code is byte-identical (modulo the timestamp header); slicing a 16x Benchy plate for a K2 drops from 78.5s to 27.3s wall (2.9x) on a 16-core Linux box, single Benchy from 8.9s to 5.6s. Co-authored-by: grant0013 --- src/libslic3r/GCode/GCodeProcessor.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 0ab32a6780..cc5036846e 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -3120,7 +3120,7 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers // Orca: Integrate filament consumption for purging performed to an external device and controlled via macros // (eg. Happy Hare) in the filament consumption stats. if (boost::starts_with(comment, GCodeProcessor::External_Purge_Tag)) { - std::regex numberRegex(R"(\d+\.\d+)"); + static const std::regex numberRegex(R"(\d+\.\d+)"); std::smatch match; std::string line(comment); if (std::regex_search(line, match, numberRegex)) { @@ -4976,7 +4976,7 @@ void GCodeProcessor::process_M572(const GCodeReader::GCodeLine &line) void GCodeProcessor::process_SET_PRESSURE_ADVANCE(const GCodeReader::GCodeLine& line) { - std::regex regex(R"(SET_PRESSURE_ADVANCE\s+(?:.*\s+)?ADVANCE\s*=\s*([\d.]+))"); + static const std::regex regex(R"(SET_PRESSURE_ADVANCE\s+(?:.*\s+)?ADVANCE\s*=\s*([\d.]+))"); std::smatch matches; if (std::regex_search(line.raw(), matches, regex) && matches.size() > 1) { @@ -5198,9 +5198,9 @@ void GCodeProcessor::process_M205(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_SET_VELOCITY_LIMIT(const GCodeReader::GCodeLine& line) { // handle SQUARE_CORNER_VELOCITY - std::regex pattern("\\sSQUARE_CORNER_VELOCITY\\s*=\\s*([0-9]*\\.*[0-9]*)"); + static const std::regex square_corner_velocity_pattern("\\sSQUARE_CORNER_VELOCITY\\s*=\\s*([0-9]*\\.*[0-9]*)"); std::smatch matches; - if (std::regex_search(line.raw(), matches, pattern) && matches.size() == 2) { + if (std::regex_search(line.raw(), matches, square_corner_velocity_pattern) && matches.size() == 2) { float _jerk = 0; try { @@ -5213,8 +5213,8 @@ void GCodeProcessor::process_SET_VELOCITY_LIMIT(const GCodeReader::GCodeLine& li } } - pattern = std::regex("\\sACCEL\\s*=\\s*([0-9]*\\.*[0-9]*)"); - if (std::regex_search(line.raw(), matches, pattern) && matches.size() == 2) { + static const std::regex accel_pattern("\\sACCEL\\s*=\\s*([0-9]*\\.*[0-9]*)"); + if (std::regex_search(line.raw(), matches, accel_pattern) && matches.size() == 2) { float _accl = 0; try { @@ -5227,8 +5227,8 @@ void GCodeProcessor::process_SET_VELOCITY_LIMIT(const GCodeReader::GCodeLine& li } } - pattern = std::regex("\\sVELOCITY\\s*=\\s*([0-9]*\\.*[0-9]*)"); - if (std::regex_search(line.raw(), matches, pattern) && matches.size() == 2) { + static const std::regex velocity_pattern("\\sVELOCITY\\s*=\\s*([0-9]*\\.*[0-9]*)"); + if (std::regex_search(line.raw(), matches, velocity_pattern) && matches.size() == 2) { float _speed = 0; try {