mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-03 08:20:28 +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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
string::string(const size_t size, const char ch) noexcept : string()
|
||||
{
|
||||
resize(size, ch);
|
||||
}
|
||||
|
||||
string::string(const char* s, const size_t size) noexcept : string()
|
||||
{
|
||||
append(s, size);
|
||||
size_t need;
|
||||
char* p2;
|
||||
if (ckd_add(&need, n, 1 /* nul */ + 15))
|
||||
__builtin_trap();
|
||||
need &= -16;
|
||||
if (!(p2 = (char*)malloc(need)))
|
||||
__builtin_trap();
|
||||
memset(p2, ch, n);
|
||||
p2[n] = 0;
|
||||
set_big_string(p2, n, need);
|
||||
}
|
||||
|
||||
const char*
|
||||
|
|
63
ctl/string.h
63
ctl/string.h
|
@ -48,18 +48,59 @@ class string
|
|||
using const_iterator = const char*;
|
||||
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 */
|
||||
{
|
||||
if (isbig())
|
||||
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;
|
||||
const char* c_str() const noexcept;
|
||||
|
||||
|
@ -83,13 +124,6 @@ class string
|
|||
size_t find(char, 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
|
||||
{
|
||||
ctl::swap(blob, s.blob);
|
||||
|
@ -283,6 +317,9 @@ class string
|
|||
|
||||
private:
|
||||
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
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue