对象的通用缓存

发布于 2024-07-06 03:45:17 字数 439 浏览 8 评论 0原文

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

  • 您使用键来查找对象(与 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 缓存一样简单。

欢迎任何建议!

尼克

Does anyone know any implementation of a templated cache of objects?

  • You use a key to find object (the same as in std::map<>)
  • You specify a maximum number of objects that can be in the cache at the same time
  • There are facilities to create an object not found in the cache
  • There are facilities to know when an object is discarded from the cache

For example :

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

...

It can be as simple as a LRU or MRU cache.

Any suggestions are welcomed!

Nic

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

楠木可依 2024-07-13 03:45:17

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

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

从大的角度来看,缓存代码会减慢进程,同时又是多余的。

In an application I can hardly imagine it would speed/boost up performance to store objects that apparently can be re-created (hip: since they can be automatically discarded, when the cache tops).
A sw cache would require memory-fetching through associativism code, surely slower then memory allocation and constructor running (mostly memory initializations).

With the exception of manual user configuration to avoid the paging mechanism (precisely to boost performance, btw), most OS "caches" memory for you on disk... it's "paging", a form of "high-cost caching", because nothing gets thrown away, and it's done by specific HW, a sub-processing unit called Memory Management Unit...

A caching-code, in the big picture, would be slowing processes while being redundant.

飘逸的'云 2024-07-13 03:45:17

我已经将一个由映射和链表构建的相对简单的 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;
    }
};

我相信这符合您的标准。 有什么需要补充或者改变的吗?

Ive put together a relatively simple LRU cache built from a map and a linked list:

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

Which I believe meets your criteria. Anything need to be added, or changed?

别闹i 2024-07-13 03:45:17

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

You can use the Boost.MultiIndex library.
It is easy to implement a MRU cache.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文