mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-05 17:30:27 +00:00
More small-string optimizations
This commit is contained in:
parent
be005b63e3
commit
d1b6715018
2 changed files with 84 additions and 29 deletions
|
@ -38,29 +38,47 @@ string::destroy_big() noexcept
|
||||||
free(b->p);
|
free(b->p);
|
||||||
}
|
}
|
||||||
|
|
||||||
string::string(const char* s) noexcept : string()
|
void
|
||||||
|
string::init_big(const string& s) noexcept
|
||||||
{
|
{
|
||||||
append(s, strlen(s));
|
char* p2;
|
||||||
|
if (s.size() >= s.capacity() >> 1) {
|
||||||
|
if (!(p2 = (char*)malloc(s.capacity())))
|
||||||
|
__builtin_trap();
|
||||||
|
set_big_string(p2, s.size(), s.capacity());
|
||||||
|
} else {
|
||||||
|
init_big(string_view(s));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string::string(const string& s) noexcept : string()
|
void
|
||||||
|
string::init_big(const string_view s) noexcept
|
||||||
{
|
{
|
||||||
append(s.data(), s.size());
|
size_t need;
|
||||||
|
char* p2;
|
||||||
|
if (ckd_add(&need, s.n, 1 /* nul */ + 15))
|
||||||
|
__builtin_trap();
|
||||||
|
need &= -16;
|
||||||
|
if (!(p2 = (char*)malloc(need)))
|
||||||
|
__builtin_trap();
|
||||||
|
memcpy(p2, s.p, s.n);
|
||||||
|
p2[s.n] = 0;
|
||||||
|
set_big_string(p2, s.n, need);
|
||||||
}
|
}
|
||||||
|
|
||||||
string::string(const string_view s) noexcept : string()
|
void
|
||||||
|
string::init_big(const size_t n, const char ch) noexcept
|
||||||
{
|
{
|
||||||
append(s.p, s.n);
|
size_t need;
|
||||||
}
|
char* p2;
|
||||||
|
if (ckd_add(&need, n, 1 /* nul */ + 15))
|
||||||
string::string(const size_t size, const char ch) noexcept : string()
|
__builtin_trap();
|
||||||
{
|
need &= -16;
|
||||||
resize(size, ch);
|
if (!(p2 = (char*)malloc(need)))
|
||||||
}
|
__builtin_trap();
|
||||||
|
memset(p2, ch, n);
|
||||||
string::string(const char* s, const size_t size) noexcept : string()
|
p2[n] = 0;
|
||||||
{
|
set_big_string(p2, n, need);
|
||||||
append(s, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
|
|
63
ctl/string.h
63
ctl/string.h
|
@ -48,18 +48,59 @@ class string
|
||||||
using const_iterator = const char*;
|
using const_iterator = const char*;
|
||||||
static constexpr size_t npos = -1;
|
static constexpr size_t npos = -1;
|
||||||
|
|
||||||
|
string() noexcept
|
||||||
|
{
|
||||||
|
__builtin_memset(blob, 0, sizeof(size_t) * 2);
|
||||||
|
// equivalent to set_small_size(0) but also zeroes memory
|
||||||
|
*(((size_t*)blob) + 2) = __::sso_max << (sizeof(size_t) - 1) * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
string(const string_view s) noexcept
|
||||||
|
{
|
||||||
|
if (s.n <= __::sso_max) {
|
||||||
|
__builtin_memcpy(blob, s.p, s.n);
|
||||||
|
__builtin_memset(blob + s.n, 0, __::sso_max - s.n);
|
||||||
|
set_small_size(s.n);
|
||||||
|
} else {
|
||||||
|
init_big(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit string(const size_t n, const char ch = 0) noexcept
|
||||||
|
{
|
||||||
|
if (n <= __::sso_max) {
|
||||||
|
__builtin_memset(blob, ch, n);
|
||||||
|
__builtin_memset(blob + n, 0, __::sso_max - n);
|
||||||
|
set_small_size(n);
|
||||||
|
} else {
|
||||||
|
init_big(n, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string(const char* const p) noexcept
|
||||||
|
: string(string_view(p, __builtin_strlen(p)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
string(const string& r) noexcept
|
||||||
|
{
|
||||||
|
if (r.isbig())
|
||||||
|
init_big(r);
|
||||||
|
else
|
||||||
|
__builtin_memcpy(blob, r.blob, __::string_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
string(const char* const p, const size_t n) noexcept
|
||||||
|
: string(string_view(p, n))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
~string() /* noexcept */
|
~string() /* noexcept */
|
||||||
{
|
{
|
||||||
if (isbig())
|
if (isbig())
|
||||||
destroy_big();
|
destroy_big();
|
||||||
}
|
}
|
||||||
|
|
||||||
string(string_view) noexcept;
|
|
||||||
string(const char*) noexcept;
|
|
||||||
string(const string&) noexcept;
|
|
||||||
string(const char*, size_t) noexcept;
|
|
||||||
explicit string(size_t, char = 0) noexcept;
|
|
||||||
|
|
||||||
string& operator=(string) noexcept;
|
string& operator=(string) noexcept;
|
||||||
const char* c_str() const noexcept;
|
const char* c_str() const noexcept;
|
||||||
|
|
||||||
|
@ -83,13 +124,6 @@ class string
|
||||||
size_t find(char, size_t = 0) const noexcept;
|
size_t find(char, size_t = 0) const noexcept;
|
||||||
size_t find(string_view, size_t = 0) const noexcept;
|
size_t find(string_view, size_t = 0) const noexcept;
|
||||||
|
|
||||||
string() noexcept
|
|
||||||
{
|
|
||||||
__builtin_memset(blob, 0, sizeof(size_t) * 2);
|
|
||||||
// equivalent to set_small_size(0) but also zeroes memory
|
|
||||||
*(((size_t*)blob) + 2) = __::sso_max << (sizeof(size_t) - 1) * 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(string& s) noexcept
|
void swap(string& s) noexcept
|
||||||
{
|
{
|
||||||
ctl::swap(blob, s.blob);
|
ctl::swap(blob, s.blob);
|
||||||
|
@ -283,6 +317,9 @@ class string
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void destroy_big() noexcept;
|
void destroy_big() noexcept;
|
||||||
|
void init_big(const string&) noexcept;
|
||||||
|
void init_big(string_view) noexcept;
|
||||||
|
void init_big(size_t, char) noexcept;
|
||||||
|
|
||||||
inline bool isbig() const noexcept
|
inline bool isbig() const noexcept
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue