12

有谁知道对象模板缓存的任何实现?

  • 您使用一个键来查找对象(与 std::map<> 中的相同)
  • 您指定可以同时在缓存中的最大对象数
  • 有一些工具可以创建在缓存中找不到的对象
  • 有一些工具可以知道何时从缓存中丢弃对象

例如 :

typedef cache<int, MyObj*> MyCache;
MyCache oCache;
oCache.SetSize(1);
oCache.Insert(make_pair(1, new MyObj());
oCache.Touch(1);
MyObj* oldObj = oCache.Delete(1);

...

它可以像 LRU 或 MRU 缓存一样简单。

欢迎任何建议!

网卡

4

3 回答 3

3

您可以使用Boost.MultiIndex库。实现MRU 缓存很容易。

于 2016-04-07T12:24:01.343 回答
1

我已经将一个相对简单的 LRU 缓存放在一起,它是由一个映射和一个链表构建的:

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

我认为符合您的标准。有什么需要添加或更改的吗?

于 2016-02-03T20:49:29.313 回答
-5

在一个应用程序中,我几乎无法想象它会加速/提高性能来存储显然可以重新创建的对象(臀部:因为当缓存达到顶峰时它们可以被自动丢弃)。sw 缓存需要通过关联代码获取内存,这肯定比内存分配和构造函数运行(主要是内存初始化)慢。

除了手动用户配置以避免分页机制(精确地提高性能,顺便说一句),大多数操作系统为您在磁盘上“缓存”内存......它是“分页”,一种“高成本缓存”的形式,因为没有东西被扔掉,它是由特定的硬件完成的,一个称为内存管理单元的子处理单元......

从大局来看,缓存代码会在冗余的同时减慢进程。

于 2008-09-23T20:41:01.857 回答