C++ 动态控制c+中的成员数+;数据结构
我目前正在编写一个处理数据库的程序 我可以要求不同的选项并获得不同数量的列 问题是,数据将是千兆字节的信息,我无法制作一个包含所有可能选项的结构。我需要能够动态地创建一个只包含我需要的成员而不包含其他成员的结构 我还想要比为每个可能的情况创建一个结构更好的东西 以下是表格示例:C++ 动态控制c+中的成员数+;数据结构,c++,optimization,data-structures,c++11,containers,C++,Optimization,Data Structures,C++11,Containers,我目前正在编写一个处理数据库的程序 我可以要求不同的选项并获得不同数量的列 问题是,数据将是千兆字节的信息,我无法制作一个包含所有可能选项的结构。我需要能够动态地创建一个只包含我需要的成员而不包含其他成员的结构 我还想要比为每个可能的情况创建一个结构更好的东西 以下是表格示例: smallint(6) - varchar(255) - double - int(11) smallint(6) - varchar(255) - double - double - double - int(11)
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)
<> P>有什么方法可以创建具有C++中的动态成员数量的结构,它与普通结构一样有效?
[编辑]
这里有一个使用@Industrial抗抑郁药思想的解决方案。它可以工作,但唯一的问题是它似乎比普通结构慢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;
}
#包括
类列
{
公众:
列(uint64无偏移,常量类型_info*p类型)
{
m_nOffset=nOffset;
m_p类型=p类型;
}
uint64 m_nOffset;
const type_info*m_pType;
};
结构元素
{
公众:
模板
无效集(uint64 N列,T值)
{
if(*m_pColumnList)[n列].m_pType==&typeid(T))
{
uint64 nOffset=(*m_pColumnList)[n列].m_nOffset;
*(重新解释铸造(m_pData+nOffset))=值;
}
其他的
{
断言(0);
}
}
模板
T&Get(uint64 N列)
{
//此处没有用于测试速度的类型检查
uint64 nOffset=(*m_pColumnList)[n列].m_nOffset;
返回*重新解释铸件(m_pData+无偏移);
}
受保护的:
无符号字符*m_pData;
std::vector*m_pColumnList;
好友类元素列表;
};
类元素列表
{
公众:
uElementList()
{
m_nEndOffset=0;
}
模板
void AddType()
{
列(m_nEndOffset和typeid(T));
m_columnlist.向后推(列);
m_nEndOffset+=sizeof(T);
}
void CreateElement()
{
uw元素;
element.m_pData=新的无符号字符[m_nEndOffset];
element.m_pColumnList=&m_columnlist;
m_元素列表。向后推(元素);
}
UWElement和运算符[](int64 NPO)
{
返回m_元素列表[NPO];
}
私人:
std::向量m_列列表;
uint64 m_nEndOffset;
std::向量m_元素列表;
};
int main()
{
结构相似结构
{
双a;
int b;
INTC;
};
相似结构相似;
向量相似表;
相似列表。推回(相似);
元素列表;
AddType();
AddType();
AddType();
CreateElement();
//测试写入速度
uint64 nTick=GetTickCount64();
对于(inti=0;i如何使用链接列表。您可以使用新的操作符动态地为每个节点分配内存
性能可能不等于使用预定义结构时获得的性能,但它提供了更多的控制
如果仍然只想创建动态结构,可以在结构内部使用联合
更多信息:如果您愿意使用这些库,这里有一些想法
可以尝试使用的二维数组。对于动态二维数组,可以使用
根据文档,boost::variant
具有:
高效的实现——尽可能基于堆栈(请参阅
要求提供更多细节)
我以前成功地使用了boost::variant
的向量来表示数据库行,但我的内存需求比您的内存需求要小得多。您可能需要对这种方法进行基准测试,看看它是否可行
如果使用这种方法,可能需要某种方法在运行时确定给定数据库列的索引。如果要按名称访问列,可以使用std::map
或boost::unordered_map
在列名和列索引之间进行映射
希望这会有所帮助。内存分配是否能够处理1亿个对象,每个对象都有一个包含4到10个元素的链接列表?所有1亿个对象是否会同时使用?我希望不会。需要时,您必须继续分配/取消分配。是的,我确实同时需要所有对象,这就是问题所在。我在mom中批量加载所有对象ent是一个固定的数据结构,它工作得又好又快。我现在无法想象如何创建一个快速的动态结构。如果是这样的话,我不建议使用链接列表。可能在结构内部使用联合体?一旦有了这些数据,你需要如何处理它?数据会用列号索引吗?然后你需要一个标题结构,带有启动数据索引,需要一个内存块来保存列数据,还需要模板化的get和set方法,这些方法使用头索引并重新解释二进制文件data@Industrial-抗抑郁剂是我认为唯一有效的解决方案,但我发现在使用数据的任何地方都需要使用标题结构,而不是像elegan那样t、 此解决方案还可能引入难以解决的bug,并损坏系统heap@VaughnCato我将迭代多次并尽可能快地读取每列的所有值。将每列保留在适当类型的向量中如何?由于更好的打包,它可能比结构向量更有效。boost::variant将不起作用,因为每个变量对象使用16个字节,这将使我的列表的大小增加一倍以上。