From cf536b848b94fe624019013803944da3712e67ea Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 11 May 2022 09:19:37 +0300 Subject: [PATCH] Revert "strings: reduce time spent in Builder.writeln (very frequently called)" This reverts commit b53b1cc7cb4dc65d46342fa5a30d6ca22a71f6a1. --- vlib/strings/builder.c.v | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/vlib/strings/builder.c.v b/vlib/strings/builder.c.v index 490b94d770..be216c997d 100644 --- a/vlib/strings/builder.c.v +++ b/vlib/strings/builder.c.v @@ -12,9 +12,7 @@ pub type Builder = []u8 // new_builder returns a new string builder, with an initial capacity of `initial_size` pub fn new_builder(initial_size int) Builder { mut res := Builder([]u8{cap: initial_size}) - unsafe { - res.flags = .noslices - } + unsafe { res.flags.set(.noslices) } 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. [inline] 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 @@ -145,15 +143,14 @@ pub fn (mut b Builder) go_back_to(pos int) { // writeln appends the string `s`, and then a newline character. [inline] pub fn (mut b Builder) writeln(s string) { - new_len := b.len + s.len + 1 - b.ensure_cap(new_len) - unsafe { - &u8(b.data)[new_len - 1] = u8(`\n`) - if s.len > 0 { - vmemcpy(&u8(b.data) + b.len, s.str, s.len) - } - b.len = new_len + // for c in s { + // b.buf << c + // } + if s.len > 0 { + unsafe { b.push_many(s.str, s.len) } } + // b.buf << []u8(s) // TODO + b << u8(`\n`) } // 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 pub fn (mut b Builder) ensure_cap(n int) { + // code adapted from vlib/builtin/array.v if n <= b.cap { return } - new_data := unsafe { malloc(u64(n) * u64(b.element_size)) } - if b.data != 0 { - unsafe { vmemcpy(new_data, b.data, b.len) } - unsafe { free(b.data) } + + new_data := vcalloc(n * b.element_size) + if b.data != voidptr(0) { + 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 { b.data = new_data