私は現在、データベースを扱うプログラムを書いています。
さまざまなオプションを要求して、可変数の列を取得できます。
問題は、データが数ギガバイトの情報になり、すべての可能なオプションで 1 つの構造を作成できないことです。必要なメンバーのみを使用して構造を動的に作成できる必要があります。
また、考えられるケースごとに構造を作成するよりも優れたものが欲しいです!
テーブルの例を次に示します。
smallint(6) - varchar(255) - double - int(11)
smallint(6) - varchar(255) - double - double - double - int(11)
smallint(6) - smallint(6) - varchar(255) - varchar(255) - double - int(11)
通常の構造体と同じくらい効率的な動的な数のメンバーを持つ構造体を C++ で作成する方法はありますか?
[編集]
@Industrial-antidepressant のアイデアを使用したソリューションを次に示します。それは機能しますが、通常の構造体よりも4倍遅いように見える唯一の問題です。
#include <windows.h>
class Column
{
public:
Column(uint64 nOffset, const type_info* pType)
{
m_nOffset = nOffset;
m_pType = pType;
}
uint64 m_nOffset;
const type_info* m_pType;
};
struct UWElement
{
public:
template<class T>
void Set(uint64 nColumn, T value)
{
if ((*m_pColumnList)[nColumn].m_pType == &typeid(T))
{
uint64 nOffset = (*m_pColumnList)[nColumn].m_nOffset;
*(reinterpret_cast<T*>(m_pData + nOffset)) = value;
}
else
{
assert(0);
}
}
template<class T>
T& Get(uint64 nColumn)
{
// No type check here to test speed
uint64 nOffset = (*m_pColumnList)[nColumn].m_nOffset;
return *reinterpret_cast<T*>(m_pData + nOffset);
}
protected:
unsigned char* m_pData;
std::vector<Column>* m_pColumnList;
friend class UWElementList;
};
class UWElementList
{
public:
UWElementList()
{
m_nEndOffset = 0;
}
template<class T>
void AddType()
{
Column column(m_nEndOffset, &typeid(T));
m_columnlist.push_back(column);
m_nEndOffset += sizeof(T);
}
void CreateElement()
{
UWElement element;
element.m_pData = new unsigned char[m_nEndOffset];
element.m_pColumnList = &m_columnlist;
m_elementList.push_back(element);
}
UWElement& operator[](int64 nPos)
{
return m_elementList[nPos];
}
private:
std::vector<Column> m_columnlist;
uint64 m_nEndOffset;
std::vector<UWElement> m_elementList;
};
int main()
{
struct SimilarStruct
{
double a;
int b;
int c;
};
SimilarStruct similar;
vector<SimilarStruct> similarList;
similarList.push_back(similar);
UWElementList list;
list.AddType<double>();
list.AddType<int>();
list.AddType<int>();
list.CreateElement();
// Test writing speed
uint64 nTick = GetTickCount64();
for(int i=0; i<100*1000*1000; i++)
{
//list[0].Set<double>(0,(double)1.1); //Speed 140ms
list[0].Get<double>(0) = (double)1.1; //Speed 109ms
//similarList[0].a = (double)1.1; //Speed 31ms
}
cout << GetTickCount64() - nTick << endl;
double d=0;
// Test reading speed
nTick = GetTickCount64();
for(int i=0; i<100*1000*1000; i++)
{
d += list[0].Get<double>(0); //Speed 94ms
//d += similarList[0].a; //Speed 93ms
}
cout << GetTickCount64() - nTick;
return d;
}
スピードアップに役立つ最適化はありますか?