C++成员函数结果缓存实现
C++ Member Function Results Cache Implementation
我有一些函数需要很长时间,但结果总是一样的,所以我想缓存结果。我已经编写了一个结果缓存的通用实现,它可以被继承,为派生类提供缓存功能。
#include "includes.h"
// Interface so values can be stored polymophically in a vector
class CacheInterface
{
public:
virtual ~CacheInterface(){}
virtual std::string GetName() const = 0;
};
// Stores a cached value and its name
template <class T>
class CachedValue : public CacheInterface
{
public:
CachedValue(const T & value, const std::string & name):
_value(value),
_name(name)
{
}
std::string GetName() const
{
return _name;
}
void SetValue(const T & value)
{
_value = value;
}
T _value;
std::string _name;
};
// Stores the cache results, can be inherited from or held as a member.
class ResultCache
{
public:
template <class T> void AddToCache(const T & value, const std::string & name)
{
// Search if it is there
for (shared_ptr<CacheInterface> & cache : _cached_items)
{
if (cache->GetName() == name)
{
shared_ptr<CachedValue<T>> cache_value (boost::reinterpret_pointer_cast<CachedValue<T>>(cache));
cache_value->_value = value;
return;
}
}
// Make a new cache value and add it
shared_ptr<CacheInterface> cached_item(new CachedValue<T>(value, name));
_cached_items.push_back(cached_item);
}
// Returns true if cache exists for a name
bool IsInCache(const std::string & name)
{
for (shared_ptr<CacheInterface> & cache : _cached_items)
{
if (cache->GetName() == name)
{
return true;
}
}
return false;
}
// Reads a value from the cache
template <class T> void ReadFromCache(T & output, const std::string & name)
{
for (shared_ptr<CacheInterface> & cache : _cached_items)
{
if (cache->GetName() == name)
{
// Is reinterpret cast safe?
shared_ptr<CachedValue<T>> cache_value (boost::reinterpret_pointer_cast<CachedValue<T>>(cache));
output = cache_value->_value;
}
}
}
// Clears the cache values
void ClearCache()
{
_cached_items.clear();
}
// Clear cache on copy and assign?
private:
std::vector<shared_ptr<CacheInterface>> _cached_items;
};
// Macros simplified use in code.
#define IS_IN_CACHE(x) IsInCache(#x)
#define READ_FROM_CACHE(x) ReadFromCache(x, #x)
#define CACHE_RESULT(x) AddToCache(x, #x)
用法:
#include "UnitTest++.h"
#include "resultcache.h"
#include "accuratetimer.h"
class TestCacheClass : public ResultCache
{
public:
int LongFunction()
{
int i = 34;
if (IS_IN_CACHE(i))
{
READ_FROM_CACHE(i);
return i;
}
else
{
sleep(1);
i = 9932;
CACHE_RESULT(i);
return i;
}
}
};
TEST(Cache1)
{
TestCacheClass test_class;
AccurateTimer timer;
CHECK_EQUAL(test_class.LongFunction(), 9932);
CHECK_CLOSE(timer.GetTimeDuration(), 1.0, 0.2);
timer.Reset();
CHECK_EQUAL(test_class.LongFunction(), 9932);
CHECK_CLOSE(timer.GetTimeDuration(), 0.0, 0.2);
}
在这里使用重新解释演员阵容安全吗?
如果使用std::map而不是std::vector来从名称中查找值,这会更快吗。我已经看到,在许多地方,由于预取器,std::vector的速度要快得多。
在许多地方,由于预取器,std::vector的速度要快得多。
我想你说的预取器是指CPU分支预测和L1缓存?或者你指的是别的什么?过映射的速度在很大程度上取决于缓存的大小和缓存中的项目。如果它的项目相对较少,那么向量可以更快,但如果不是,那么使用Map-当向量变大时,映射的O(log(n))或无序映射的0(1)将比O(n)更快。[如果它很小,你可能会更好地评估更简单的代码,而不是有限的性能增益。]
为了回答您最初的问题,重新解释将虚拟接口指针强制转换为具体类型是不安全的,因为如果您更改派生类的继承(例如,继承两个接口),编译器可能会修改vtable。您需要静态强制转换。
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 如何实现缓存友好的动态二进制树
- C++实现文件缓存(如 Web 浏览器)的库
- C++11中的无锁缓存实现
- LRU 缓存C++实现问题
- C++成员函数结果缓存实现
- LRU缓存C++实现
- 在c++中实现LRU缓存-编译错误
- 如何实现线程安全的LRU缓存回收
- 如何使用std::shared_ptr实现缓存管理器
- 如何在c++中实现与抽象类指针向量的缓存一致性
- 如何在树访问器中实现每个节点的缓存
- 实现一个倾斜关联数据缓存c++
- 实现缓存数据的c++ CGI