From 3697548e35d8edb2558217b129db9fec89137c34 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 19 Jan 2015 13:25:04 +0000 Subject: [PATCH] Use a single allocation for SharedString::Storage --- src/shared_string.cc | 2 +- src/shared_string.hh | 30 +++++++++++++++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/shared_string.cc b/src/shared_string.cc index 01104e00..52605342 100644 --- a/src/shared_string.cc +++ b/src/shared_string.cc @@ -35,7 +35,7 @@ void StringRegistry::debug_stats() const for (auto& st : m_strings) { total_refcount += st.second->refcount - 1; - total_size += (int)st.second->content.size(); + total_size += (int)st.second->length; } write_debug(" data size: " + to_string(total_size) + ", mean: " + to_string((float)total_size/count)); write_debug(" refcounts: " + to_string(total_refcount) + ", mean: " + to_string((float)total_refcount/count)); diff --git a/src/shared_string.hh b/src/shared_string.hh index 8a84bf48..a0a4a8e1 100644 --- a/src/shared_string.hh +++ b/src/shared_string.hh @@ -14,19 +14,31 @@ class SharedString : public StringView public: struct Storage : UseMemoryDomain { - int refcount = 0; - Vector content; + int refcount; + int length; + char data[1]; - Storage(StringView str) + StringView strview() const { return {data, length}; } + + static Storage* create(StringView str) { - content.reserve((int)str.length() + 1); - content.assign(str.begin(), str.end()); - content.push_back('\0'); + const int len = (int)str.length(); + void* ptr = Storage::operator new(sizeof(Storage) + len); + Storage* res = reinterpret_cast(ptr); + memcpy(res->data, str.data(), len); + res->refcount = 0; + res->length = len; + res->data[len] = 0; + return res; + } + + static void destroy(Storage* s) + { + Storage::operator delete(s, sizeof(Storage) + s->length); } - StringView strview() const { return {&content.front(), &content.back()}; } friend void inc_ref_count(Storage* s) { ++s->refcount; } - friend void dec_ref_count(Storage* s) { if (--s->refcount == 0) delete s; } + friend void dec_ref_count(Storage* s) { if (--s->refcount == 0) Storage::destroy(s); } }; SharedString() = default; @@ -34,7 +46,7 @@ public: { if (not str.empty()) { - m_storage = new Storage{str}; + m_storage = Storage::create(str); StringView::operator=(m_storage->strview()); } }