More ctl::string optimization (#1232)

Moves some isbig checks into string.h, enabling smarter optimizations to
be made on small strings. Also we no longer zero out our string prior to
calling the various constructors, buying back the performance we lost on
big strings when we made the small-string optimization. We further add a
little optimization to the big_string copy constructor: if the string is
using half or more of its capacity, then we don’t recompute capacity and
just take the old string’s. As well, the copy constructor always makes a
small string when it will fit, even if copied from a big string that got
truncated.

This also reworks the test to follow the idiom adopted elsewhere re stl,
and adds a helper function to tell if a string is small based on data().
This commit is contained in:
Steven Dee (Jōshin) 2024-06-20 11:52:12 -07:00 committed by GitHub
parent 9a5a13854d
commit 7e780e57d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 165 additions and 74 deletions

View file

@ -23,9 +23,19 @@
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
using String = ctl::string;
// #include <string>
// using String = std::string;
// #define ctl std
using String = ctl::string;
#undef ctl
inline bool
issmall(const String& s)
{
return s.capacity() == sizeof(s) &&
s.data() == reinterpret_cast<const char*>(&s);
}
int
main()
@ -358,15 +368,14 @@ main()
String s;
if constexpr (std::is_same_v<ctl::string, decltype(s)>) {
// tests the small-string optimization on ctl::string
char* d = s.data();
for (int i = 0; i < 23; ++i) {
s.append("a");
if (s.data() != d) {
if (!issmall(s)) {
return 79 + i;
}
}
s.append("a");
if (s.data() == d) {
if (issmall(s)) {
return 103;
}
} else {
@ -380,6 +389,21 @@ main()
}
}
{
String s("arst", 4);
for (int i = 0; i < 30; ++i) {
s.append("a");
}
s.resize(4);
if (s != "arst")
return 105;
if constexpr (std::is_same_v<ctl::string, decltype(s)>) {
String r(s);
if (issmall(s) || !issmall(r))
return 106;
}
}
CheckForMemoryLeaks();
return 0;
}