2

私は現在、データベースを扱うプログラムを書いています。

さまざまなオプションを要求して、可変数の列を取得できます。

問題は、データが数ギガバイトの情報になり、すべての可能なオプションで 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;
}

スピードアップに役立つ最適化はありますか?

4

2 に答える 2

1
于 2012-10-22T03:23:05.510 に答える
0

リンクリストを使用するのはどうですか。new 演算子を使用して、その場で各ノードにメモリを割り当てることができます。

パフォーマンスは、事前定義された構造体を使用した場合に得られるパフォーマンスと等しくない場合がありますが、より多くの制御が提供されます。

それでも動的構造のみを作成したい場合は、構造内で共用体を使用できます。

詳細: C++ の動的構造

于 2012-10-22T01:47:29.157 に答える