オブジェクトの汎用キャッシュ


12

オブジェクトのテンプレートキャッシュの実装を知っている人はいますか?

  • あなたがオブジェクトを見つけるためにキーを使用します(STDと同じ::マップ<>)
  • あなたがあります
  • 同時にキャッシュにあることができるオブジェクトの最大数を指定します

    :オブジェクトはたとえばキャッシュ

から破棄されたときに知っている施設がありますキャッシュ

  • で見つかっていないオブジェクトを作成するための施設

    LRUまたはMRUキャッシュと同じくらい簡単です。

    どのような提案も歓迎されます!

    アプリケーションでニック

  • -6

    私はほとんどそれが/どうやら再作成することができますストアオブジェクトにパフォーマンスを押し上げるスピード想像することはできません(ヒップ:ときにキャッシュのトップス、彼らは自動的に、破棄することができるので)。 スワッシュキャッシュは、連想主義コードを介したメモリフェッチを必要とします。メモリ割り当てとコンストラクタの実行(主にメモリの初期化)は遅くなります。

    ページングの仕組みを避けるために(正確にはパフォーマンスを向上させるためには、btwを除く)、ほとんどのOSはディスク上にあなたのメモリを "キャッシュ"します... "ページング"メモリマネジメントユニットと呼ばれるサブ処理ユニットである特定のHWによって行われます。

    キャッシングコードは、冗長性のためにプロセスを遅くすることになります。私はあなたの基準を満たしていると信じて

    template<typename K, typename V, typename Map = std::unordered_map<K, typename std::list<K>::iterator>> 
    class LRUCache 
    { 
        size_t maxSize; 
        Map data; 
        std::list<K> usageOrder; 
        std::function<void(std::pair<K, V>)> onEject = [](std::pair<K, V> x){}; 
    
        void moveToFront(typename std::list<K>::iterator itr) 
        { 
         if(itr != usageOrder.begin()) 
          usageOrder.splice(usageOrder.begin(), usageOrder, itr); 
        } 
    
    
        void trimToSize() 
        { 
         while(data.size() > maxSize) 
         { 
          auto itr = data.find(usageOrder.back()); 
    
          onEject(std::pair<K, V>(itr->first, *(itr->second))); 
          data.erase(usageOrder.back()); 
          usageOrder.erase(--usageOrder.end()); 
         } 
        } 
    
    public: 
        typedef std::pair<const K, V> value_type; 
        typedef K key_type; 
        typedef V mapped_type; 
    
    
        LRUCache(size_t maxEntries) : maxSize(maxEntries) 
        { 
         data.reserve(maxEntries); 
        } 
    
        size_t size() const 
        { 
         return data.size(); 
        } 
    
        void insert(const value_type& v) 
        { 
         usageOrder.push_front(v.first); 
         data.insert(typename Map::value_type(v.first, usageOrder.begin())); 
    
         trimToSize(); 
        } 
    
        bool contains(const K& k) const 
        { 
         return data.count(k) != 0; 
        } 
    
        V& at(const K& k) 
        { 
         auto itr = data.at(k); 
         moveToFront(itr); 
         return *itr; 
        } 
    
    
        void setMaxEntries(size_t maxEntries) 
        { 
         maxSize = maxEntries; 
         trimToSize(); 
        } 
    
        void touch(const K& k) 
        { 
         at(k); 
        } 
    
        template<typename Compute> 
        V& getOrCompute(const K& k) 
        { 
         if(!data.contains(k)) insert(value_type(k, Compute())); 
         return(at(k)); 
        } 
    
        void setOnEject(decltype(onEject) f) 
        { 
         onEject = f; 
        } 
    }; 
    

      0

    オブジェクトの(再)作成がキー - >値ルックアップよりもはるかに遅い場合はどうなりますか?すべてのコンストラクタが「ほとんどのメモリの初期化」であるわけではありません。 23 9月. 082008-09-23 22:10:29

      0

    私はなぜdownvoteを得る:私は答えを提供していない。 だから私は1つを取得しようとしている: 今MMUは、最近使用されていないキャッシュされたオブジェクトを含むメモリに低使用量のフラグを立てるので、ハードディスク上のページファイルに送信されます。 HDD。したがって、HDDからキャッシュされていないオブジェクト、オブジェクトを再作成するためのiso実行コードを再フェッチすることは、非常に厄介な環境のセットでしか「正しい」ものではありません。 @Nicolas:具体的な状況はどうですか? 22 6月. 102010-06-22 19:55:59

    +1

    私はあなたがCPUキャッシュと他のタイプのデータキャッシュを混在させると思っています。 OPはCPUではなくデータキャッシュを探しました。 27 2月. 132013-02-27 10:41:49


    1

    アイブ氏は、一緒にマップし、リンクされたリストから構築された比較的単純なLRUキャッシュを置きます。何かを追加または変更する必要はありますか?

      0

    マップのパフォーマンスは簡単に恐ろしくなることがあります。私はあなたがハッシュテーブルを使用することをお勧めします。できるだけコンパイル時間を固定サイズにしてください。リストを追加する代わりにスキャンしてください。 11 2月. 162016-02-11 23:47:07

      0

    @BitWhistlerこれはハッシュテーブルを使用します。デフォルトでは、ハッシュテーブルであるstd :: unordered_mapです。私は、コンパイル時の固定サイズは良い考えではないと思います。サイズを格納するためのオーバーヘッドが非常に低く、必要に応じてサイズを変更できます。リストを保持してスキャンするのではなく、どういう意味ですか? LRUエントリを削除できるように、リストには挿入順序が記録されます。 12 2月. 162016-02-12 20:57:29

      0

    申し訳ありませんが、あなたが正しいです。私はstd :: mapを見たと思った。それでも、すべてを事前割り当てすると、再割り当てしないという利点があります。再割り当てはここで最大のコストです。リストにも同じ考えがあります。あなたはこれらのノードをすべて浮かべているでしょう...エントリーに年齢を持っているか、エントリー内に単独でリンクされたリストを侵入させる方が良いです。 16 2月. 162016-02-16 11:07:17


    1

    Boost.MultiIndexライブラリを使用できます。 MRU cacheを実装するのは簡単です。