Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Kernel: Increase kstd::string performance with this one simple trick!
Browse files Browse the repository at this point in the history
God, I should overhaul the kstd containers. This code is terrible.

Anyway, string concatenation in the kernel is now way faster because we're not stupid about it - we use an exponential reallocation strategy to amortize the cost with repeated allocations and avoid unnecessary copies when appending c-style strings.
  • Loading branch information
byteduck committed Mar 2, 2024
1 parent 59a7ab5 commit 229ff2d
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 21 deletions.
80 changes: 60 additions & 20 deletions kernel/kstd/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "string.h"
#include "cstring.h"
#include "kstdlib.h"

namespace kstd {
string::string(): _size(1), _length(0), _cstring(new char[1]) {
Expand All @@ -29,21 +30,33 @@ namespace kstd {
_length = string._length;
_size = string._size;
_cstring = new char[_size];
strcpy(_cstring, string._cstring);
memcpy(_cstring, string._cstring, _size);
}

string::string(string&& str) noexcept:
_length(str._length),
_size(str._size),
_cstring(str._cstring)
{
str._length = 0;
str._size = 0;
str._cstring = nullptr;
}

string::string(const char* str) {
_length = strlen(str);
_size = _length + 1;
_cstring = new char[_size];
strcpy(_cstring, str);
memcpy(_cstring, str, _size);
}

string::string(const char* str, size_t length): _length(length + 1) {
string::string(const char* a, size_t size_a, const char* b, size_t size_b) {
_length = size_a + size_b;
_size = _length + 1;
_cstring = new char[_size];
_cstring[_length - 1] = '\0';
memcpy(_cstring, str, _length - 1);
memcpy(_cstring, a, size_a);
memcpy(_cstring + size_a, b, size_b);
_cstring[_length] = '\0';
}

string::~string(){
Expand All @@ -64,29 +77,46 @@ namespace kstd {
return *this;
}

string& string::operator+=(const string& str) {
_length = _length + str._length;
_size = _length + 1;

char* buffer = new char[_size];
strcpy(buffer, _cstring);
strcat(buffer, str._cstring);
string& string::operator=(kstd::string&& str) noexcept {
if (&str == this)
return *this;

_length = str._length;
_size = str._size;
delete[] _cstring;
_cstring = buffer;
_cstring = str._cstring;

str._length = 0;
str._size = 0;
str._cstring = nullptr;

return *this;
}

string string::operator+(const string& str) const {
char* buffer = new char[_length + str._length + 1];
strcpy(buffer, _cstring);
strcat(buffer, str._cstring);
string& string::operator+=(const string& str) {
append(str._cstring, str._length);
return *this;
}

string ret = string(buffer);
delete[] buffer;
string& string::operator+=(const char* str) {
append(str, strlen(str));
return *this;
}

return ret;
void string::append(const char* str, size_t length) {
auto new_length = _length + length;
expand_to(new_length + 1);
memcpy(_cstring + _length, str, length);
_cstring[new_length] = '\0';
_length = new_length;
}

string string::operator+(const string& str) const {
return {_cstring, _length, str._cstring, str._length};
}

string string::operator+(const char* str) const {
return {_cstring, _length, str, (size_t) strlen(str)};
}

string& string::operator=(const char* str) {
Expand Down Expand Up @@ -193,4 +223,14 @@ namespace kstd {
char *string::data() const {
return _cstring;
}

void string::expand_to(size_t min_size) {
if (min_size <= _size)
return;
_size = max(min_size, _size * 2);
if (_cstring)
_cstring = (char*) krealloc(_cstring, _size);
else
_cstring = new char[_size];
}
}
10 changes: 9 additions & 1 deletion kernel/kstd/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ namespace kstd {
public:
string();
string(const string& string);
string(string&& string) noexcept;
string(const char* string);
string(const char* string, size_t length);
~string();

string& operator=(const char* str);
string& operator=(const string& str);
string& operator=(string&& str) noexcept;
string& operator+=(const string& str);
string& operator+=(const char* str);
string operator+(const string& b) const;
string operator+(const char* str) const;
bool operator==(const string& str) const;
bool operator==(const char* str) const;
bool operator!=(const string& str) const;
Expand All @@ -50,7 +53,12 @@ namespace kstd {
size_t find_last_of(const string& str, size_t end = -1) const;
size_t find_last_of(const char* str, size_t end = -1) const;
size_t find_last_of(const char c, size_t end = -1) const;

private:
string(const char* a, size_t size_a, const char* b, size_t size_b);
void append(const char* str, size_t length);
void expand_to(size_t min_size);

size_t _size;
size_t _length;
char* _cstring;
Expand Down

0 comments on commit 229ff2d

Please sign in to comment.