mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-27 18:02:17 +03:00
Small String Optimization (#5690)
Reduce String memory overhead from 24 bytes to 16 bytes by limiting the maximum string length to <64Kbytes (which is larger than heap so no effective problem). Add Small String Optimization, SSO, which instead of allocating pointers to small strings on the heap will store the string in place of the pointer in the class. This should reduce memory fragmentation as Save up to 12 chars (11 + \0) in String itself by using the terminating \0 in the inline string as a flag to identify if this is a SSO or a heap string. Add a host test that verifies that no memory is allocated until a full 11 characters are assigned to a string, as well as checking all intermediate values. No user code changes should be required to work with this optimization.
This commit is contained in:
committed by
GitHub
parent
1959311180
commit
7369133681
@ -268,3 +268,96 @@ TEST_CASE("String sizes near 8b", "[core][String]")
|
||||
REQUIRE(!strcmp(s16.c_str(),"123456789012345_"));
|
||||
REQUIRE(!strcmp(s17.c_str(),"1234567890123456_"));
|
||||
}
|
||||
|
||||
TEST_CASE("String SSO works", "[core][String]")
|
||||
{
|
||||
// This test assumes that SSO_SIZE==8, if that changes the test must as well
|
||||
String s;
|
||||
s += "0";
|
||||
REQUIRE(s == "0");
|
||||
REQUIRE(s.length() == 1);
|
||||
const char *savesso = s.c_str();
|
||||
s += 1;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01");
|
||||
REQUIRE(s.length() == 2);
|
||||
s += "2";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012");
|
||||
REQUIRE(s.length() == 3);
|
||||
s += 3;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123");
|
||||
REQUIRE(s.length() == 4);
|
||||
s += "4";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234");
|
||||
REQUIRE(s.length() == 5);
|
||||
s += "5";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345");
|
||||
REQUIRE(s.length() == 6);
|
||||
s += "6";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456");
|
||||
REQUIRE(s.length() == 7);
|
||||
s += "7";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234567");
|
||||
REQUIRE(s.length() == 8);
|
||||
s += "8";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345678");
|
||||
REQUIRE(s.length() == 9);
|
||||
s += "9";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789");
|
||||
REQUIRE(s.length() == 10);
|
||||
s += "a";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789a");
|
||||
REQUIRE(s.length() == 11);
|
||||
if (sizeof(savesso) == 4) {
|
||||
s += "b";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789ab");
|
||||
REQUIRE(s.length() == 12);
|
||||
s += "c";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abc");
|
||||
REQUIRE(s.length() == 13);
|
||||
} else {
|
||||
s += "bcde";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789abcde");
|
||||
REQUIRE(s.length() == 15);
|
||||
s += "fghi";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789abcdefghi");
|
||||
REQUIRE(s.length() == 19);
|
||||
s += "j";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghij");
|
||||
REQUIRE(s.length() == 20);
|
||||
s += "k";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijk");
|
||||
REQUIRE(s.length() == 21);
|
||||
s += "l";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijkl");
|
||||
REQUIRE(s.length() == 22);
|
||||
s += "m";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklm");
|
||||
REQUIRE(s.length() == 23);
|
||||
s += "nopq";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopq");
|
||||
REQUIRE(s.length() == 27);
|
||||
s += "rstu";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopqrstu");
|
||||
REQUIRE(s.length() == 31);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user