Optimize FastVector for fast push_next() operation.

This commit is contained in:
Bartosz Taudul 2018-04-14 17:12:41 +02:00
parent 6120b3e922
commit 4eb205ad18

View File

@ -18,8 +18,8 @@ public:
FastVector( size_t capacity ) FastVector( size_t capacity )
: m_ptr( (T*)tracy_malloc( sizeof( T ) * capacity ) ) : m_ptr( (T*)tracy_malloc( sizeof( T ) * capacity ) )
, m_size( 0 ) , m_write( m_ptr )
, m_capacity( capacity ) , m_end( m_ptr + capacity )
{ {
} }
@ -34,70 +34,70 @@ public:
FastVector& operator=( const FastVector& ) = delete; FastVector& operator=( const FastVector& ) = delete;
FastVector& operator=( FastVector&& ) = delete; FastVector& operator=( FastVector&& ) = delete;
bool empty() const { return m_size == 0; } bool empty() const { return m_ptr == m_write; }
size_t size() const { return m_size; } size_t size() const { return m_write - m_ptr; }
T* data() { return m_ptr; } T* data() { return m_ptr; }
const T* data() const { return m_ptr; }; const T* data() const { return m_ptr; };
T* begin() { return m_ptr; } T* begin() { return m_ptr; }
const T* begin() const { return m_ptr; } const T* begin() const { return m_ptr; }
T* end() { return m_ptr + m_size; } T* end() { return m_write; }
const T* end() const { return m_ptr + m_size; } const T* end() const { return m_write; }
T& front() { assert( m_size > 0 ); return m_ptr[0]; } T& front() { assert( !empty() ); return m_ptr[0]; }
const T& front() const { assert( m_size > 0 ); return m_ptr[0]; } const T& front() const { assert( !empty() ); return m_ptr[0]; }
T& back() { assert( m_size > 0 ); return m_ptr[m_size - 1]; } T& back() { assert( !empty() ); return m_write[-1]; }
const T& back() const { assert( m_size > 0 ); return m_ptr[m_size - 1]; } const T& back() const { assert( !empty() ); return m_write[-1]; }
T& operator[]( size_t idx ) { return m_ptr[idx]; } T& operator[]( size_t idx ) { return m_ptr[idx]; }
const T& operator[]( size_t idx ) const { return m_ptr[idx]; } const T& operator[]( size_t idx ) const { return m_ptr[idx]; }
T* push_next() T* push_next()
{ {
T* ret; if( m_write == m_end ) AllocMore();
if( m_size == m_capacity ) AllocMore(); return m_write++;
ret = m_ptr + m_size;
m_size++;
return ret;
} }
void clear() void clear()
{ {
m_size = 0; m_write = m_ptr;
} }
void swap( FastVector& vec ) void swap( FastVector& vec )
{ {
const auto ptr1 = m_ptr; const auto ptr1 = m_ptr;
const auto ptr2 = vec.m_ptr; const auto ptr2 = vec.m_ptr;
const auto size1 = m_size; const auto write1 = m_write;
const auto size2 = vec.m_size; const auto write2 = vec.m_write;
const auto cap1 = m_capacity; const auto end1 = m_end;
const auto cap2 = vec.m_capacity; const auto end2 = vec.m_end;
m_ptr = ptr2; m_ptr = ptr2;
vec.m_ptr = ptr1; vec.m_ptr = ptr1;
m_size = size2; m_write = write2;
vec.m_size = size1; vec.m_write = write1;
m_capacity = cap2; m_end = end2;
vec.m_capacity = cap1; vec.m_end = end1;
} }
private: private:
tracy_no_inline void AllocMore() tracy_no_inline void AllocMore()
{ {
m_capacity *= 2; const auto cap = ( m_end - m_ptr ) * 2;
T* ptr = (T*)tracy_malloc( sizeof( T ) * m_capacity ); const auto size = m_write - m_ptr;
memcpy( ptr, m_ptr, m_size * sizeof( T ) ); T* ptr = (T*)tracy_malloc( sizeof( T ) * cap );
memcpy( ptr, m_ptr, size * sizeof( T ) );
tracy_free( m_ptr ); tracy_free( m_ptr );
m_ptr = ptr; m_ptr = ptr;
m_write = m_ptr + size;
m_end = m_ptr + cap;
} }
T* m_ptr; T* m_ptr;
size_t m_size; T* m_write;
size_t m_capacity; T* m_end;
}; };
} }