2

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

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

问题是数据将是千兆字节的信息,我无法创建一个包含所有可能选项的结构。我需要能够动态地创建一个结构,其中只有我需要的成员,没有别的。

我还想要比为每个可能的情况创建一个结构更好的东西!

以下是表格示例:

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;
}

任何可以帮助加快速度的优化?

4

2 回答 2

1
于 2012-10-22T03:23:05.510 回答
0

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

如果使用预定义的结构,性能可能不等于您将获得的性能,但它提供了更多控制。

如果您仍只想创建动态结构,则可以在结构内使用联合。

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

于 2012-10-22T01:47:29.157 回答