Poco::LRUCache

Poco が幾つか持っている Cache の中で、最も基本的な Poco::LRUCache を紹介します。
LRU は Least Recently Used の略で、一番最近使われた要素へのアクセスが最も早くなります。

LRUCacheTest.cpp

Poco::Buffer に、Write/Read Delay をわざと入れた SlowBuffer を作成。
・SlowBuffer に Poco::LRUCache をかぶせて CachedSlowBuffer を作成。
・SlowBuffer と CachedSlowBuffer に対して、WriteReadTest を行い、その所要時間を表示。
・kBufferSize, kWriteDelayMSec, kReadDelayMSec を調整することで、LRUCache の効き具合を確認。
 ここでは、それぞれ 256, 3mSec, 3mSec に設定。

#include <Poco/Format.h>
#include <Poco/Buffer.h>
#include <Poco/Thread.h>
#include <Poco/LRUCache.h>
 
#include "ScopedElapsedTime.h"
#include "PrepareConsoleLogger.h"
 
template <class TKey, class TValue>
class SlowBuffer : public Poco::Buffer<TValue>
{
public:
	SlowBuffer(std::size_t size, long writeDelayMSec, long readDelayMSec) :
		Poco::Buffer<TValue>(size)
	,	m_writeDelayMSec(writeDelayMSec)
	,	m_readDelayMSec(readDelayMSec)
	{
	}
 
virtual
	~SlowBuffer()
	{
	}
 
virtual
	void write(TKey index, TValue val)
	{
		Poco::Thread::sleep(m_writeDelayMSec);
		(*this)[index] = val;
	}
 
virtual
	TValue& read(TKey index)
	{
		Poco::Thread::sleep(m_readDelayMSec);
		return (*this)[index];
	}
 
private:
	const long	m_writeDelayMSec;
	const long	m_readDelayMSec;
};
 
template <class TKey, class TValue>
class CachedSlowBuffer : public SlowBuffer<TKey, TValue>, public Poco::LRUCache<TKey, TValue>
{
public:
	CachedSlowBuffer(std::size_t size, long writeDelayMSec, long readDelayMSec) :
		SlowBuffer<TKey, TValue>(size, writeDelayMSec, readDelayMSec)
	,	Poco::LRUCache<TKey, TValue>()
	{
	}
 
	~CachedSlowBuffer()
	{
	}
 
	void write(TKey index, TValue val)
	{
		Poco::LRUCache<TKey, TValue>::add(index, val);
		SlowBuffer<TKey, TValue>::write(index, val);
	}
 
	TValue& read(TKey index)
	{
		if(Poco::LRUCache<TKey, TValue>::has(index))
		{
			return *(Poco::LRUCache<TKey, TValue>::get(index));
		}
		else
		{
			TValue& val = SlowBuffer<TKey, TValue>::read(index);
			Poco::LRUCache<TKey, TValue>::add(index, val);
			return val;
		}
	}
};
 
template <class TKey, class TValue>
void WriteReadTest(SlowBuffer<TKey, TValue>& buffer, std::size_t bufferSize, const std::string& name)
{
	{
		ScopedElapsedTime msg(Poco::format("write %s (addr inc) ", name), "start", "end");
 
		TValue val = 0;
		for(TKey i=0; i<bufferSize; ++i)
		{
			buffer.write(i, val++);
		}
	}
	{
		ScopedElapsedTime msg(Poco::format("read  %s (addr dec) ", name), "start", "end");
 
		for(TKey i=bufferSize; i!=0; --i)
		{
			/*unsigned long data =*/ buffer.read(i-1);
		}
	}
	{
		ScopedElapsedTime msg(Poco::format("read  %s (addr   0) ", name), "start", "end\n");
 
		for(TKey i=0; i<bufferSize; ++i)
		{
			/*unsigned long data =*/ buffer.read(0);
		}
	}
}
 
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);
 
	const std::size_t kBufferSize	= 256;
	const long kWriteDelayMSec	= 3;
	const long kReadDelayMSec	= 3;
 
	SlowBuffer<std::size_t, unsigned long> slowBuffer(kBufferSize, kWriteDelayMSec, kReadDelayMSec);
	WriteReadTest(slowBuffer, kBufferSize, "SlowBuffer");
 
	CachedSlowBuffer<std::size_t, unsigned long> cachedSlowBuffer(kBufferSize, kWriteDelayMSec, kReadDelayMSec);
	WriteReadTest(cachedSlowBuffer, kBufferSize, "CachedSlowBuffer");
 
	return 0;
}

Results of execution

・Read が、約640倍ほど高速化。

[0] write SlowBuffer (addr inc) start
[0]  Elepsed time = 784.025mSec
[0] write SlowBuffer (addr inc) end
[0] read  SlowBuffer (addr dec) start
[0]  Elepsed time = 781.478mSec
[0] read  SlowBuffer (addr dec) end
[0] read  SlowBuffer (addr   0) start
[0]  Elepsed time = 780.122mSec
[0] read  SlowBuffer (addr   0) end
 
[0] write CachedSlowBuffer (addr inc) start
[0]  Elepsed time = 780.248mSec
[0] write CachedSlowBuffer (addr inc) end
[0] read  CachedSlowBuffer (addr dec) start
[0]  Elepsed time = 1.214mSec
[0] read  CachedSlowBuffer (addr dec) end
[0] read  CachedSlowBuffer (addr   0) start
[0]  Elepsed time = 1.197mSec
[0] read  CachedSlowBuffer (addr   0) end

Downloads

ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年5月1日からのダウンロード数:894

Subversion

・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。

Reference

http://pocoproject.org にある Cache のプレセンテーション。(PDF)

Powered by POCO Copyright © 2010 Round Square Inc. All rights reserved.


  1. はじめまして。
    ブログでコメントをいただいた SN工房 管理人です。
    コメントに気が付かず、しばらく放置になってしまいました。
    コメントありがとうございました。

    POCO のサイトを作られたんですね。

    今後も機会がありましたら、
    情報交換していきましょう。

    ではでは。

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>