builtin.string: optimize replace (#9969)

pull/9975/head
JalonSolov 2021-05-02 12:30:07 -04:00 committed by GitHub
parent dbadda84e5
commit 3175525b5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 17 additions and 19 deletions

View File

@ -299,29 +299,27 @@ pub fn (s string) replace(rep string, with string) string {
} }
// Now we know the number of replacements we need to do and we can calc the len of the new string // Now we know the number of replacements we need to do and we can calc the len of the new string
new_len := s.len + idxs.len * (with.len - rep.len) new_len := s.len + idxs.len * (with.len - rep.len)
mut b := unsafe { malloc(new_len + 1) } // add a newline just in case mut b := unsafe { malloc(new_len + 1) } // add space for the null byte at the end
// Fill the new string // Fill the new string
mut idx_pos := 0
mut cur_idx := idxs[idx_pos]
mut b_i := 0 mut b_i := 0
for i := 0; i < s.len; i++ { mut s_idx := 0
if i == cur_idx { for _, rep_pos in idxs {
// Reached the location of rep, replace it with "with" for i in s_idx .. rep_pos { // copy everything up to piece being replaced
for j in 0 .. with.len {
unsafe { unsafe {
b[b_i] = with[j] b[b_i] = s[i]
} }
b_i++ b_i++
} }
// Skip the length of rep, since we just replaced it with "with" s_idx = rep_pos + rep.len // move string index past replacement
i += rep.len - 1 for i in 0 .. with.len { // copy replacement piece
// Go to the next index unsafe {
idx_pos++ b[b_i] = with[i]
if idx_pos < idxs.len {
cur_idx = idxs[idx_pos]
} }
} else { b_i++
// Rep doesnt start here, just copy }
}
if s_idx < s.len { // if any original after last replacement, copy it
for i in s_idx .. s.len {
unsafe { unsafe {
b[b_i] = s[i] b[b_i] = s[i]
} }