diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2025-01-30 20:16:34 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2025-01-30 20:16:34 -0800 |
commit | 6f8115f23d0cb4225cd652abad65557d5fe7ffd9 (patch) | |
tree | 9e6b7ad05de26b924c9062c5683cb812c66ddf55 | |
parent | b04ded61081cb729fb0979d98148025815e998da (diff) | |
download | txr-6f8115f23d0cb4225cd652abad65557d5fe7ffd9.tar.gz txr-6f8115f23d0cb4225cd652abad65557d5fe7ffd9.tar.bz2 txr-6f8115f23d0cb4225cd652abad65557d5fe7ffd9.zip |
get-csv: use unsafe version string-extend.
Another almost 16% speedup.
* lib.c (us_length_STR): New static function.
(string_extend): Use us_length_STR, since we know the
object is of type STR.
(us_string_extend_STR_CHR): New function.
(length_str): Handle STR case via use_length_STR.
* lib.h (us_string_extend_STR_CHR): Declared.
* stream.c (get_csv): Use us_string_extend_STR_CHR
instead of string_extend.
-rw-r--r-- | lib.c | 49 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | stream.c | 10 |
3 files changed, 49 insertions, 11 deletions
@@ -5384,6 +5384,15 @@ val downcase_str(val str) return out; } +static val us_length_STR(val str, val self) +{ + if (!str->st.len) { + set(mkloc(str->st.len, str), num(wcslen(str->st.str))); + str->st.alloc = c_num(str->st.len, self) + 1; + } + return str->st.len; +} + val string_extend(val str, val tail, val finish_in) { val self = lit("string-extend"); @@ -5391,7 +5400,7 @@ val string_extend(val str, val tail, val finish_in) type_check(self, str, STR); { val finish = default_null_arg(finish_in); - cnum len = c_fixnum(length_str(str), self); + cnum len = c_fixnum(us_length_STR(str, self), self); cnum oalloc = str->st.alloc; cnum alloc = oalloc, delta, needed; @@ -5436,6 +5445,38 @@ val string_extend(val str, val tail, val finish_in) return str; } +val us_string_extend_STR_CHR(val str, val ch, val finish, val self) +{ + cnum len = c_fixnum(us_length_STR(str, self), self); + cnum oalloc = str->st.alloc; + cnum alloc = oalloc, needed; + + if (NUM_MAX - 2 < len) + uw_throwf(alloc_error_s, lit("~a: overflow"), self, nao); + + needed = len + 2; + + if (needed > alloc || finish) { + if (finish) + alloc = needed; + else if (alloc >= (NUM_MAX - NUM_MAX / 3)) + alloc = NUM_MAX; + else + alloc = max(alloc + alloc / 2, needed); + + if (alloc != oalloc) { + str->st.str = chk_wrealloc(str->st.str, alloc); + str->st.alloc = alloc; + } + } + + str->st.len = num_fast(len + 1); + str->st.str[len] = convert(wchar_t, c_n(ch)); + str->st.str[len + 1] = 0; + + return str; +} + val string_finish(val str) { val self = lit("string-finish"); @@ -5528,11 +5569,7 @@ val length_str(val str) lazy_str_force(str); return length_str(str->ls.prefix); case STR: - if (!str->st.len) { - set(mkloc(str->st.len, str), num(wcslen(str->st.str))); - str->st.alloc = c_num(str->st.len, self) + 1; - } - return str->st.len; + return us_length_STR(str, self); default: type_mismatch(lit("length-str: ~s is not a string"), str, nao); } @@ -1093,6 +1093,7 @@ val upcase_str(val str); val downcase_str(val str); val string_extend(val str, val tail, val finish); val string_finish(val str); +val us_string_extend_STR_CHR(val str, val ch, val finish, val self); val string_set_code(val str, val code); val string_get_code(val str); val stringp(val str); @@ -5482,10 +5482,10 @@ val get_csv(val source_opt) if (empty(field)) state = qfield; else - string_extend(field, ch, nil); + us_string_extend_STR_CHR(field, ch, nil, self); break; default: - string_extend(field, ch, nil); + us_string_extend_STR_CHR(field, ch, nil, self); break; } break; @@ -5495,7 +5495,7 @@ val get_csv(val source_opt) state = quot; break; default: - string_extend(field, ch, nil); + us_string_extend_STR_CHR(field, ch, nil, self); break; } break; @@ -5507,7 +5507,7 @@ val get_csv(val source_opt) state = rfield; break; case '"': - string_extend(field, ch, nil); + us_string_extend_STR_CHR(field, ch, nil, self); state = qfield; break; case '\n': @@ -5515,7 +5515,7 @@ val get_csv(val source_opt) done = 1; break; default: - string_extend(field, ch, nil); + us_string_extend_STR_CHR(field, ch, nil, self); state = rfield; break; } |