From cfc52d7e6a02adadc4897c9531a85ddaa8dc9266 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Fri, 13 Oct 2017 21:58:38 +0800 Subject: [PATCH] Regex: use intrusive linked list for the free saves instead of a Vector --- src/regex_impl.hh | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/regex_impl.hh b/src/regex_impl.hh index f1068dca2..4a2995048 100644 --- a/src/regex_impl.hh +++ b/src/regex_impl.hh @@ -185,7 +185,11 @@ public: private: struct Saves { - int refcount; + union // ref count when in use, next_free when in free list + { + int refcount; + Saves* next_free; + }; Iterator pos[1]; }; @@ -194,10 +198,10 @@ private: { kak_assert(not copy or pos != nullptr); const auto count = m_program.save_count; - if (not m_free_saves.empty()) + if (m_first_free != nullptr) { - Saves* res = m_free_saves.back(); - m_free_saves.pop_back(); + Saves* res = m_first_free; + m_first_free = res->next_free; res->refcount = 1; if (copy) std::copy(pos, pos + count, res->pos); @@ -208,7 +212,7 @@ private: } void* ptr = ::operator new (sizeof(Saves) + (count-1) * sizeof(Iterator)); - Saves* saves = new (ptr) Saves{1, {copy ? pos[0] : Iterator{}}}; + Saves* saves = new (ptr) Saves{{1}, {copy ? pos[0] : Iterator{}}}; for (size_t i = 1; i < count; ++i) new (&saves->pos[i]) Iterator{copy ? pos[i] : Iterator{}}; m_saves.push_back(saves); @@ -218,7 +222,10 @@ private: void release_saves(Saves* saves) { if (saves and --saves->refcount == 0) - m_free_saves.push_back(saves); + { + saves->next_free = m_first_free; + m_first_free = saves; + } }; struct Thread @@ -479,7 +486,7 @@ private: RegexExecFlags m_flags; Vector m_saves; - Vector m_free_saves; + Saves* m_first_free = nullptr; Saves* m_captures = nullptr; };