I'm using vectors to create matrix and the vector itself is consuming a large space. So I implemented a version that would use less memory and, if possible, be as fast or faster than std::vector
.
How can I improve the performance and is there anything that should be changed?
#ifndef __DATAARRAY_H__
#define __DATAARRAY_H__
#include <memory>
#include "core/Exceptions/ArgumentException.h"
template <size_t S> class Sizer { };
namespace Core
{
#pragma pack(1)
template <class DataType, class MaxSizeType>
class DataArray
{
public:
DataArray() :m_iDataSize(0), m_aData(nullptr), m_iDataCapacity(0){
}
DataArray(MaxSizeType size) :m_iDataSize(0){
_Reserve(size);
}
DataArray(const DataArray& dArray)
{
_Reserve(dArray.m_iDataCapacity);
_CopyData(dArray);
}
void reserve(MaxSizeType size){
}
void resize(MaxSizeType size){
if (size < m_iDataSize)
{
_Delete_Data(m_aData + size, m_aData + m_iDataSize);
m_iDataSize = size;
}
else if (m_iDataSize < size){
_Reserve(size);
DataType* pData = (m_aData + m_iDataSize);
for (; pData < m_aData + size; ++pData) {
new (pData)DataType;
}
m_iDataSize = size;
}
}
void push_back(DataType element){
if (m_iDataCapacity <= m_iDataSize)
{
_Reserve(m_iDataCapacity + 1);
}
new (m_aData + m_iDataSize)DataType(element);
m_iDataSize++;
}
DataType& operator[](MaxSizeType id)
{
if (id < 0 || id >= size())
throw std::invalid_argument("Not enought memory");
return m_aData[id];
}
DataType& operator=(const DataArray& dArray)
{
if (this == &dArray)
return *this;
_Delete_m_aData();
_Reserve(dArray.m_iDataCapacity);
_CopyData(dArray);
return *this;
}
MaxSizeType size(){
return m_iDataSize;
}
MaxSizeType Capacity(){
return m_iDataCapacity;
}
~DataArray(){
_Delete_m_aData();
}
protected:
inline void _Reserve(MaxSizeType size){
if (size > m_iDataCapacity){
DataType* new_Data = (DataType*)std::realloc(m_aData, sizeof(DataType)*size);
if (new_Data != NULL){
m_aData = new_Data;
m_iDataCapacity = size;
}
else{
_Delete_m_aData();
throw std::invalid_argument("Not enought memory");
}
}
}
inline void _CopyData(const DataArray& dArray){
DataType* pOrig = dArray.m_aData;
DataType* pDest = m_aData;
DataType* pOriEnd = pOrig + dArray.m_iDataSize;
for (; pOrig < pOriEnd; ++pDest, ++pOrig)
{
new (pDest)DataType(*pOrig);
}
m_iDataSize = dArray.m_iDataSize;
}
inline void _Delete_m_aData()
{
_Delete_Data(m_aData, m_aData + m_iDataSize);
m_iDataSize = 0;
m_iDataCapacity = 0;
free(m_aData);
}
inline void _Delete_Data(DataType* begin, DataType* end)
{
DataType* pData = begin;
for (; pData < end; ++pData) {
((DataType*)pData)->~DataType();
}
}
MaxSizeType m_iDataCapacity;
MaxSizeType m_iDataSize;
DataType* m_aData;
};
#pragma pack()
}
#endif
Sizer
for? \$\endgroup\$if possible, be as fast or faster than std::vector
Yep; not going to happen.std::vector
is highly optimized, has had thousands of people look at the code for over a decade picking it apart and making it as efficient as possible. You are not going to come in and write something faster or more stable. If you do things perfectly you may achieve as fast but that's unlikely. \$\endgroup\$std::vector
to store a 2D or 3D array. See stackoverflow.com/questions/936687/… for example. You only need each row to be a separatevector
if you need to add a column on the fly without shuffling around all existing row data (or if you need a "ragged" array where different rows are different lengths). You want your whole matrix stored in one big block of memory, not each row allocated and tracked separately. \$\endgroup\$