我想在我的项目中进行一些缓存。
让我的API为int foo(int a, float b, float c, int d, char e)
现在在我的项目中,有很多调用以上耗时的API,重复了a,b,c,d和e的值。现在我想用这些参数作为键来存储这个函数的返回值。
假设我的通话顺序是
foo(23, 3.45, 4.5, 90, 'd') // returns 1000, so I need to store it in cache as (23,3.45, 4.5, 90, 'd')->1000
foo(30, 1.2, 3.5, 100, 'e') // returns 2000, so I need to store it in cache as (30, 1.2, 3.5, 100, 'e')->2000
foo(23, 3.45, 4.5, 90, 'd') // No need to call this API, I just check in my cache value associated with
//(23, 3.45, 4.5, 90, 'd'), which is already stored as 1000
在C ++中实现上述最佳策略应该是什么?哪种数据结构最适合制作缓存表?
答案 0 :(得分:2)
一个关键注意事项:缓存很困难。
人们常常认为缓存可以解决所有问题,但是他们忘记考虑它带来的问题。非托管缓存只不过是一个巨大的内存泄漏。两种注意策略:
通常,当我们听到缓存时,我们认为LRU(最近最少使用)缓存。这些缓存受到大小的限制,并且当缓存已满时,最近最少使用的条目被逐出。 注意:可能会导致多线程争用,因为只读访问实际上意味着修改值。
这样的缓存是根据两个元素实现的:
如果你走这条路,我建议使用Boost.MultiIndex库。有一个MRU implementation的例子,与你的需求非常相似。
答案 1 :(得分:1)
如果您可以使用提升,请查看boost::unordered_map,否则您可以使用std::map。您必须提供仿函数来生成密钥。
答案 2 :(得分:0)
它并不总是有效并且在某种程度上取决于编译器,但您可以查看使用函数属性。您可能感兴趣的是 const 或纯属性。 热也可能会引起人们的兴趣。
答案 3 :(得分:0)
好问题。你有几个选择。首先,将所有值放入结构中:
struct values
{
int a;
float b;
...
};
如果序列中的一个值最具代表性,则可以使用std::map
将该代表值映射到“存储桶”。让我们说最具代表性的是float b
:
std::map< float, std::list < std::pair< values, int> > >
由std::list
表示,并存储值结构和结果值对(在这种情况下为int
)。
从值到结果int
声明一个映射。为此,您应该允许values
结构与地图中的其他结构进行比较,因此您必须编写operator<()
int operator<(values const& left, values const& right)
{
if (left.a < left.b) ... // compare two values objects
}
然后像往常一样声明地图:
std::map<values, int>
还有其他问题,例如你必须处理的复制构造函数等,但这就是这个想法。
最后注意事项,您也可以将std::map
替换为unordered_map
。
答案 4 :(得分:0)
将它们全部放在结构中
struct mykey{ int a; float b; float c; int d; char e; };
然后将它们写入并散列结构,并将其用作键
int foo(int a, float b, float c, int d, char e)
{
mykey tk = { a, b, c, d, e };
guid key = md5( &tk, sizeof( tk ) );
答案 5 :(得分:0)
我使用嵌套地图,因此您使用第一个参数从地图查找地图,直到使用最后一个参数查找的最终地图,结果是先前缓存的foo值。
当你到达最后一张地图并发现没有为这个参数设置调用foo时,你只需要为最后一个参数存储foo的结果。
答案 6 :(得分:0)
我建议使用Hash table。您只需要计算数据的哈希函数。如果散列足够强,则可以存储它和输出值,而不存储参数。此外,这个metod应该比使用std :: map更快。
在C ++中,这可以使用unordered_map或std :: hash_map来实现。 使用非常简单的哈希函数就足够了,例如The String hash function。
顺便说一句,存储参数输出值的方法称为Memoization