C++简单的缓存设计用于函数输出
C++ simple cache design for function output
我认为这是众所周知的解决方案中一个非常常见的问题,但我并没有能够找到。所以我在这里寻求建议。
问题陈述
考虑以下设置:
class A; // some class
const A f(const A&); // an _expensive_ function
void do_stuff()
{
A a;
a.modify(...);
do_stuff1(f(a)); // compute f(a)
do_stuff2(f(a)); // use cached value of f(a)
a.modify(...);
do_stuff3(f(a)); // recompute f(a)
}
我希望f(a)
的返回值缓存在第一个和但是在对a.modify()
的第二次调用之后被丢弃。EDIT:在实践中,对f(a)
的调用将在不同的作用域中。
以下是我探索过的一些解决方案,值得一提。
解决方案1:中央缓存
使用时间戳
我可以想象一个简单的解决方案,包括向类A
添加一个时间戳函数CCD_ 5可以检查并决定是否需要更新其缓存的结果,存储在中央缓存中的某个位置。我想这也意味着要改变f
至的签名
const A& f(const A&);
问题1:对于中央缓存,我们需要一种机制来销毁当CCD_ 8被破坏时CCD_。
使用哈希码
除了问题1,这似乎很简单。但当A
代表CCD_ 10。我想应该排除动态多态性在这里所以我们忘记了为std::vector<...>
的子类添加时间戳这意味着压倒一切。然而,我们可以计算一些散列码或UUID基于a
的内容——假设它比计算便宜得多f(a)
-并将中央缓存建立在这些散列码的基础上。但我们面临问题1再次出现。
解决方案2:耦合对象
我还没有找到如何实现这一点,但想法是让a
通知当a
被写入或销毁时,f(a)
的缓存,但当只是从中读取。如果没有动态多态性,我想不出如何做到这一点,并且在不减慢使用CCD_ 17或迭代器,为每个修改的元素向缓存发送通知。
问题2:找到一种将更改集定界为a
的机制,以便对每组更改仅使缓存无效一次。
我想到了在a
上启用写访问的代理(灵感来自这个概念互斥体(,但无法想出任何工作代码。
有什么想法吗?
我用这样的接口做过类似的事情:
class F
{
public:
virtual int f(int a)=0;
};
class Cache : public F
{
public:
Cache(F &f) : f(f) { }
int f(int a) { /*caching logic here, calls f.f() if not found from cache */ }
F &f;
};
class Impl : public F
{
int f(int a) { /* real implementation here */ }
};
然后它只是决定在哪里使用缓存逻辑:
Impl i;
Cache c(i);
c.f(10); // put to cache with key 10
c.f(10); // found from cache
c.f(11); // put to cache with key 11
你就不能这么做吗:
const A &cacheA = f(a);
do_stuff1(cacheA); // compute f(a)
do_stuff2(cacheA); // use cached value of f(a)
我可能遗漏了一些重要的细节,但您不能仅为此目的使用LRU缓存吗?
让f成为a的成员。然后,您可以在a的实例中决定是否可以重用缓存的结果。
- boost::bind()类似的东西,但用于函数调用
- 为什么通用参考概念不适用于函数指针的地图插入
- 为什么保守调整大小不适用于函数中的 Ref 变量?
- 用于C++函数的自动 C 包装器
- 函数指针类型不能用于函数原型
- 如何将"using"用于函数?
- 指针或局部变量,用于函数的输出参数
- C 类模板扣除(P0091R0)用于函数参数
- 用于函数签名的专用模板
- 为什么关键字“显式”不适用于函数参数
- 预期的"("用于函数式铸造或类型构造
- 将模板用于函数时出错
- 部分模板专用化可能不适用于函数,但重载不是一回事吗?
- if 语句不适用于函数
- 将数组用于函数输入参数
- 如何确定哪个 Windows DLL 用于函数调用
- 转换运算符不适用于函数参数
- 为什么参数相关查找不适用于函数模板dynamic_pointer_cast
- 用于函数样式强制转换或类型构造的预期 c++ Xcode '('
- c++14用于函数绑定的可变lambda捕获