From 1abcf06bf64f707b2ddbd7efc879d5a8d567ab5f Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 16 Aug 2022 22:20:04 +0300 Subject: [PATCH] PIVector some optimize code --- libs/main/containers/pivector.h | 132 +++++++++++++++++++++----------- 1 file changed, 87 insertions(+), 45 deletions(-) diff --git a/libs/main/containers/pivector.h b/libs/main/containers/pivector.h index 09dc90fd..4d2e85e0 100644 --- a/libs/main/containers/pivector.h +++ b/libs/main/containers/pivector.h @@ -127,7 +127,7 @@ public: //! \~english Constructs an empty array. //! \~russian Создает пустой массив. - inline PIVector(): piv_data(0), piv_size(0), piv_rsize(0) { + inline PIVector() { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) } @@ -135,7 +135,7 @@ public: //! This constructor reserve `size` and copy from `data` pointer. //! \~russian Создает массив из указателя на данные `data` и размер `size`. //! То есть выделяет память для `size` элементов и копирует данные из указателя `data`. - inline PIVector(const T * data, size_t size): piv_data(0), piv_size(0), piv_rsize(0) { + inline PIVector(const T * data, size_t size) { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) alloc(size); newT(piv_data, data, piv_size); @@ -143,7 +143,7 @@ public: //! \~english Copy constructor. //! \~russian Копирующий конструктор. - inline PIVector(const PIVector & v): piv_data(0), piv_size(0), piv_rsize(0) { + inline PIVector(const PIVector & v) { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) alloc(v.piv_size); newT(piv_data, v.piv_data, piv_size); @@ -158,7 +158,7 @@ public: //! PIVector v{1,2,3}; //! piCout << v; // {1, 2, 3} //! \endcode - inline PIVector(std::initializer_list init_list): piv_data(0), piv_size(0), piv_rsize(0) { + inline PIVector(std::initializer_list init_list) { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) alloc(init_list.size()); newT(piv_data, init_list.begin(), init_list.size()); @@ -166,9 +166,9 @@ public: //! \~english Contructs array with size `size` filled elements `e`. //! \~russian Создает массив из `size` элементов заполненных `e`. - inline PIVector(size_t size, const T & e = T()): piv_data(0), piv_size(0), piv_rsize(0) { + inline PIVector(size_t size, const T & e = T()) { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) - resize(size, e); + expand(size, e); } //! \~english Contructs array with size `size` and elements created by function `f(size_t i)`. @@ -184,15 +184,18 @@ public: //! PIVector v(5, [](size_t i){return i*2;}); //! piCout << v; // {0, 2, 4, 6, 8} //! \endcode - inline PIVector(size_t size, std::function f): piv_data(0), piv_size(0), piv_rsize(0) { + inline PIVector(size_t size, std::function f) { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) - resize(size, f); + expand(size, f); } //! \~english Move constructor. //! \~russian Перемещающий конструктор. - inline PIVector(PIVector && v): piv_data(v.piv_data), piv_size(v.piv_size), piv_rsize(v.piv_rsize) { + inline PIVector(PIVector && v) { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) + piv_data = v.piv_data; + piv_size = v.piv_size; + piv_rsize = v.piv_rsize; v._reset(); } @@ -201,7 +204,6 @@ public: PIINTROSPECTION_CONTAINER_FREE(T, (piv_rsize)) deleteT(piv_data, piv_size); dealloc(); - _reset(); } //! \~english Assign operator. @@ -1175,7 +1177,8 @@ public: !std::is_trivially_copyable::value , int>::type = 0> inline PIVector & clear() { - resize(0); + deleteT(piv_data, piv_size); + piv_size = 0; return *this; } template & resize(size_t new_size, const T & e = T()) { if (new_size < piv_size) { - T * de = &(piv_data[new_size]); - deleteT(de, piv_size - new_size); + deleteT(&(piv_data[new_size]), piv_size - new_size); piv_size = new_size; - } - if (new_size > piv_size) { - size_t os = piv_size; - alloc(new_size); - PIINTROSPECTION_CONTAINER_USED(T, (new_size-os)) - for (size_t i = os; i < new_size; ++i) { - elementNew(piv_data + i, e); - } + } else if (new_size > piv_size) { + expand(new_size, e); } return *this; } @@ -1290,14 +1286,8 @@ public: T * de = &(piv_data[new_size]); deleteT(de, piv_size - new_size); piv_size = new_size; - } - if (new_size > piv_size) { - size_t os = piv_size; - alloc(new_size); - PIINTROSPECTION_CONTAINER_USED(T, (new_size-os)) - for (size_t i = os; i < new_size; ++i) { - elementNew(piv_data + i, f(i)); - } + } else if (new_size > piv_size) { + expand(new_size, f); } return *this; } @@ -1306,12 +1296,14 @@ public: std::is_trivially_copyable::value , int>::type = 0> inline PIVector & _resizeRaw(size_t new_size) { +#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION) if (new_size > piv_size) { PIINTROSPECTION_CONTAINER_USED(T, (new_size-piv_size)); } if (new_size < piv_size) { PIINTROSPECTION_CONTAINER_UNUSED(T, (piv_size-new_size)); } +#endif alloc(new_size); return *this; } @@ -1436,7 +1428,10 @@ public: inline PIVector & remove(size_t index, size_t count = 1) { if (count == 0) return *this; if (index + count >= piv_size) { - resize(index); + if (index < piv_size) { + deleteT(&(piv_data[index]), piv_size - index); + piv_size = index; + } return *this; } size_t os = piv_size - index - count; @@ -1932,7 +1927,8 @@ public: //! \~\sa \a pop_front(), \a take_back(), \a take_front() inline PIVector & pop_back() { if (piv_size == 0) return *this; - resize(piv_size - 1); + deleteT(&(piv_data[piv_size-1]), 1); + piv_size = piv_size - 1; return *this; } @@ -2428,25 +2424,31 @@ public: } private: - inline void _reset() {piv_size = piv_rsize = 0; piv_data = 0;} + inline void _reset() { + piv_size = piv_rsize = 0; + piv_data = nullptr; + } + inline size_t asize(size_t s) { if (s == 0) return 0; if (piv_rsize + piv_rsize >= s && piv_rsize < s) { return piv_rsize + piv_rsize; } ssize_t t = _PIContainerConstants::minCountPoT(), s_ = s - 1; - while (s_ >> t) - ++t; + while (s_ >> t) ++t; return (1 << t); } + template::value , int>::type = 0> inline void newT(T * dst, const T * src, size_t s) { PIINTROSPECTION_CONTAINER_USED(T, s) - for (size_t i = 0; i < s; ++i) + for (size_t i = 0; i < s; ++i) { elementNew(dst + i, src[i]); + } } + template::value , int>::type = 0> @@ -2454,51 +2456,90 @@ private: PIINTROSPECTION_CONTAINER_USED(T, s) memcpy((void*)(dst), (const void*)(src), s * sizeof(T)); } + template::value , int>::type = 0> inline void deleteT(T * d, size_t sz) { PIINTROSPECTION_CONTAINER_UNUSED(T, sz) - if ((uchar*)d != 0) { + if (d != nullptr) { for (size_t i = 0; i < sz; ++i) { elementDelete(d[i]); } } } + template::value , int>::type = 0> inline void deleteT(T * d, size_t sz) { PIINTROSPECTION_CONTAINER_UNUSED(T, sz) } + template::value , int>::type = 0> - inline void elementNew(T * to, const T & from) {new(to)T(from);} + inline void elementNew(T * to, const T & from) { + new(to)T(from); + } + template::value , int>::type = 0> - inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} + inline void elementNew(T * to, T && from) { + new(to)T(std::move(from)); + } + template::value , int>::type = 0> - inline void elementNew(T1 * to, const T & from) {(*to) = from;} + inline void elementNew(T1 * to, const T & from) { + (*to) = from; + } + template::value , int>::type = 0> - inline void elementNew(T * to, T && from) {(*to) = std::move(from);} + inline void elementNew(T * to, T && from) { + (*to) = std::move(from); + } + template::value , int>::type = 0> - inline void elementDelete(T & from) {from.~T();} + inline void elementDelete(T & from) { + from.~T(); + } + template::value , int>::type = 0> inline void elementDelete(T & from) {} + inline void dealloc() { - if ((uchar*)piv_data != 0) free((uchar*)piv_data); - piv_data = 0; + if (piv_data != nullptr) free((uchar*)piv_data); + piv_data = nullptr; + piv_size = piv_rsize = 0; } + + inline void expand(size_t new_size, const T & e = T()) { + size_t os = piv_size; + alloc(new_size); + PIINTROSPECTION_CONTAINER_USED(T, (new_size-os)) + for (size_t i = os; i < new_size; ++i) { + elementNew(piv_data + i, e); + } + } + + inline void expand(size_t new_size, std::function f) { + size_t os = piv_size; + alloc(new_size); + PIINTROSPECTION_CONTAINER_USED(T, (new_size-os)) + for (size_t i = os; i < new_size; ++i) { + elementNew(piv_data + i, f(i)); + } + } + inline void alloc(size_t new_size) { if (new_size <= piv_rsize) { piv_size = new_size; @@ -2519,8 +2560,9 @@ private: piv_rsize = as; } - T * piv_data; - size_t piv_size, piv_rsize; + T * piv_data = nullptr; + size_t piv_size = 0; + size_t piv_rsize = 0; };