Revert "strings: reduce time spent in Builder.writeln (very frequently called)"

This reverts commit b53b1cc7cb.
Delyan Angelov 2022-05-11 09:19:37 +03:00 committed by Jef Roosens
parent f5885f587a
commit b9864446ab
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
1 changed files with 18 additions and 16 deletions

View File

@ -12,9 +12,7 @@ pub type Builder = []u8
// new_builder returns a new string builder, with an initial capacity of `initial_size` // new_builder returns a new string builder, with an initial capacity of `initial_size`
pub fn new_builder(initial_size int) Builder { pub fn new_builder(initial_size int) Builder {
mut res := Builder([]u8{cap: initial_size}) mut res := Builder([]u8{cap: initial_size})
unsafe { unsafe { res.flags.set(.noslices) }
res.flags = .noslices
}
return res return res
} }
@ -87,7 +85,7 @@ pub fn (mut b Builder) drain_builder(mut other Builder, other_new_cap int) {
// Note: it can panic, if there are not enough bytes in the strings builder yet. // Note: it can panic, if there are not enough bytes in the strings builder yet.
[inline] [inline]
pub fn (b &Builder) byte_at(n int) u8 { pub fn (b &Builder) byte_at(n int) u8 {
return unsafe { &u8(b.data)[n] } return unsafe { (&[]u8(b))[n] }
} }
// write appends the string `s` to the buffer // write appends the string `s` to the buffer
@ -145,15 +143,14 @@ pub fn (mut b Builder) go_back_to(pos int) {
// writeln appends the string `s`, and then a newline character. // writeln appends the string `s`, and then a newline character.
[inline] [inline]
pub fn (mut b Builder) writeln(s string) { pub fn (mut b Builder) writeln(s string) {
new_len := b.len + s.len + 1 // for c in s {
b.ensure_cap(new_len) // b.buf << c
unsafe { // }
&u8(b.data)[new_len - 1] = u8(`\n`) if s.len > 0 {
if s.len > 0 { unsafe { b.push_many(s.str, s.len) }
vmemcpy(&u8(b.data) + b.len, s.str, s.len)
}
b.len = new_len
} }
// b.buf << []u8(s) // TODO
b << u8(`\n`)
} }
// last_n(5) returns 'world' // last_n(5) returns 'world'
@ -191,13 +188,18 @@ pub fn (mut b Builder) str() string {
// ensure_cap ensures that the buffer has enough space for at least `n` bytes by growing the buffer if necessary // ensure_cap ensures that the buffer has enough space for at least `n` bytes by growing the buffer if necessary
pub fn (mut b Builder) ensure_cap(n int) { pub fn (mut b Builder) ensure_cap(n int) {
// code adapted from vlib/builtin/array.v
if n <= b.cap { if n <= b.cap {
return return
} }
new_data := unsafe { malloc(u64(n) * u64(b.element_size)) }
if b.data != 0 { new_data := vcalloc(n * b.element_size)
unsafe { vmemcpy(new_data, b.data, b.len) } if b.data != voidptr(0) {
unsafe { free(b.data) } unsafe { vmemcpy(new_data, b.data, b.len * b.element_size) }
// TODO: the old data may be leaked when no GC is used (ref-counting?)
if b.flags.has(.noslices) {
unsafe { free(b.data) }
}
} }
unsafe { unsafe {
b.data = new_data b.data = new_data