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 <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-03-21 15:26:22 +09:00
parent 9d955ba75f
commit 4ded345ebb
+7 -6
View File
@@ -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)