9

list には forward_list よりもポインター (前のポインター) が 1 つ多いため、両方が同じ数の要素を保持している場合、つまり 1<<30 の場合、list はほぼ 1/3 のメモリを使用します。右?

次に、サイズ変更を繰り返して大きくすると、forward_list はリストよりもはるかに大きくサイズ変更できる必要があります。

テストコード:

#include<forward_list>
#include<list>
#include<iostream>
int main(){
    using namespace std;
    typedef list<char> list_t;
    //typedef forward_list<char> list_t;
    list_t l;
    list_t::size_type i = 0;
    try{
        while(1){
            l.resize(i += (1<<20));
            cerr<<i<<" ";
        }
    }
    catch(...){
        cerr<<endl;
    }
    return 0;
}

驚いたことに、プロセスが強制終了されると、それらはほぼ同じサイズになります...誰でも解釈できますか?

4

2 に答える 2

9

std::list<T>より良いメモリ スニッフィングにより、aが 3 倍のエネルギーを消費するという最初の仮説が正しいことがわかるはずです。私の Windows マシンでは、GetProcessMemoryInfoを使用して簡単なメモリ使用プログラムを作成しました。

これが私のプログラムの核心です:

int main()
{
    size_t initMemory = MemoryUsage();
    std::list<unsigned char> linkedList;

    for (int i = 0; i < ITERATIONS; i++)
        linkedList.push_back(i % 256);
    size_t linkedListMemoryUsage = MemoryUsage() - initMemory;

    std::forward_list<unsigned char> forwardList;
    for (int i = 0; i < ITERATIONS; i++)
        forwardList.push_front(i % 256);
    size_t forwardListMemoryUsage = MemoryUsage() - linkedListMemoryUsage - initMemory;

    std::cout << "Bytes used by Linked List: " << linkedListMemoryUsage << std::endl;
    std::cout << "Bytes used by Forward List: " << forwardListMemoryUsage << std::endl;

    return 0;
}

リリース ビルドで実行した場合の結果:

#define ITERATIONS 128
Bytes used by Linked List: 24576
Bytes used by Forward List: 8192
8192 * 3 = 24576

これは、 cplusplus.comからの引用であり、2 つのコンテナー間に顕著なメモリの違いがあるはずであるとさえ言っています。

forward_list コンテナーとリスト コンテナーの主な設計上の違いは、最初のコンテナーは次の要素へのリンクのみを内部的に保持するのに対して、後者は要素ごとに 2 つのリンクを保持することです。ただし、要素ごとに追加のストレージを消費し、要素の挿入と削除のオーバーヘッドがわずかに長くなります。したがって、forward_list オブジェクトはリスト オブジェクトよりも効率的ですが、前方に反復することしかできません。

投稿されたコードで行うように、リストでサイズ変更関数を使用すると、メモリの違いはさらに顕著になり、std::list<T>4 倍のメモリが消費されました。

于 2012-07-19T15:06:29.747 に答える