缓存多个密钥哈希

时间:2011-05-26 22:44:32

标签: c++ c caching data-structures stl

我想在我的项目中进行一些缓存。

让我的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 ++中实现上述最佳策略应该是什么?哪种数据结构最适合制作缓存表?

7 个答案:

答案 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;
    ...
};
  1. 如果序列中的一个值最具代表性,则可以使用std::map将该代表值映射到“存储桶”。让我们说最具代表性的是float b

    std::map< float, std::list < std::pair< values, int> > >

    std::list表示,并存储值结构和结果值对(在这种情况下为int)。

  2. 从值到结果int声明一个映射。为此,您应该允许values结构与地图中的其他结构进行比较,因此您必须编写operator<()

  3.  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

相关问题