1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

builtin: speed up string concatenation and repeat() method with vmemcpy instead of for loop for copying data (#18206)

These changes almost do not speed up the program with the `-prod` flag,
since modern С compilers can do such optimization on their own, but in
normal mode, the performance gain is from 1.6 (concatenation) to 1.8 (repeat) times.

Concatenation:
Old (`for` loop):
Time (mean):          3.699 s +- 0.071 s  [User: 3.629 s, System: 0.069 s]
Range (min ... max):  3.548 s ... 3.741 s  10 runs

New (vmemcpy):
Time (mean):          2.305 s +- 0.065 s  [User: 2.263 s, System: 0.041 s]
Range (min ... max):  2.172 s ... 2.355 s  10 runs

`vmemcpy version` ran 1.60 +- 0.05 times faster than 'for loop version'
This commit is contained in:
Petr Makhnev 2023-05-19 17:18:23 +04:00 committed by GitHub
parent f67952fe84
commit a39c26507c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -725,15 +725,9 @@ fn (s string) + (a string) string {
str: unsafe { malloc_noscan(new_len + 1) } str: unsafe { malloc_noscan(new_len + 1) }
len: new_len len: new_len
} }
for j in 0 .. s.len { unsafe {
unsafe { vmemcpy(res.str, s.str, s.len)
res.str[j] = s.str[j] vmemcpy(res.str + s.len, a.str, a.len)
}
}
for j in 0 .. a.len {
unsafe {
res.str[s.len + j] = a.str[j]
}
} }
unsafe { unsafe {
res.str[new_len] = 0 // V strings are not null terminated, but just in case res.str[new_len] = 0 // V strings are not null terminated, but just in case
@ -2077,10 +2071,8 @@ pub fn (s string) repeat(count int) string {
} }
mut ret := unsafe { malloc_noscan(s.len * count + 1) } mut ret := unsafe { malloc_noscan(s.len * count + 1) }
for i in 0 .. count { for i in 0 .. count {
for j in 0 .. s.len { unsafe {
unsafe { vmemcpy(ret + i * s.len, s.str, s.len)
ret[i * s.len + j] = s[j]
}
} }
} }
new_len := s.len * count new_len := s.len * count