From 4ded345ebb2eb2a843e78e02feda8503288b9ce1 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 21 Mar 2026 15:26:22 +0900 Subject: [PATCH] mruby-regexp: use array join in gsub to avoid O(n^2) concatenation Collect replacement parts in an array and join at the end instead of repeated string += which creates intermediate string objects. Co-authored-by: Claude --- mrbgems/mruby-regexp/mrblib/string_regexp.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/mrbgems/mruby-regexp/mrblib/string_regexp.rb b/mrbgems/mruby-regexp/mrblib/string_regexp.rb index 366e14a98..ad7df6e33 100644 --- a/mrbgems/mruby-regexp/mrblib/string_regexp.rb +++ b/mrbgems/mruby-regexp/mrblib/string_regexp.rb @@ -65,27 +65,28 @@ class String def gsub(pattern, replacement = nil, &block) pattern = Regexp.new(Regexp.escape(pattern)) if pattern.is_a?(String) - result = "" + parts = [] rest = self while rest.length > 0 md = pattern.match(rest) break unless md - result += md.pre_match + parts << md.pre_match if block - result += block.call(md[0]).to_s + parts << block.call(md[0]).to_s else - result += __sub_replace(replacement.to_s, md) + parts << __sub_replace(replacement.to_s, md) end matched_len = md[0].length if matched_len == 0 # avoid infinite loop on zero-length match - result += rest[0] if rest.length > 0 + parts << rest[0] if rest.length > 0 rest = rest[1..-1] || "" else rest = md.post_match end end - result + rest + parts << rest + parts.join end def scan(pattern)