繁体   English   中英

动态控制c ++数据结构中的成员数

[英]Control dynamically the number of members in c++ data structure

我目前正在编写一个处理数据库的程序。

我可以要求不同的选项并获得可变数量的列。

问题在于数据将是千兆字节的信息,而我无法用所有可能的选项来构建一种结构。 我需要能够动态创建仅包含我需要的成员而没有其他成员的结构。

我还希望有比为每种可能的情况创建结构更好的方法!

以下是表格示例:

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)

有什么方法可以创建具有动态成员数量的结构,而这种结构的成员数量与普通结构一样高效?

[编辑]

这是使用@ 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;
}

是否有任何优化可以帮助加快速度?

如果您愿意使用Boost库,这里有一些想法。

您可以尝试使用boost::variant<list of possible types>的二维数组。 对于动态二维数组,可以使用boost::multi_array

根据文档, boost::variant具有:

高效的实现-尽可能基于堆栈(有关更多详细信息,请参见““永不空缺”保证”一节 )。

在表示数据库行之前,我已经成功使用了boost::variant向量,但是我的内存需求比您的要适度得多。 您可能必须对这种方法进行基准测试,以查看它是否可行。

如果使用这种方法,则可能需要某种方式在运行时确定给定数据库列的索引。 如果要按名称访问列,则可以使用std::mapboost::unordered_map在列名称和列索引之间进行映射。

希望这可以帮助。

如何使用链接列表。 您可以使用new运算符动态分配内存给每个节点。

该性能可能不等于使用预定义结构时所获得的性能,但是它提供了更多的控制权。

如果仍然只想创建动态结构,则可以在结构内部使用并集。

更多信息: C ++中的动态结构

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM