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日からのダウンロード数:1186
Subversion
・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。
Reference
・http://pocoproject.org にある Cache のプレセンテーション。(PDF)
![]() |
Copyright © 2010 Round Square Inc. All rights reserved. |
---|
はじめまして。
ブログでコメントをいただいた SN工房 管理人です。
コメントに気が付かず、しばらく放置になってしまいました。
コメントありがとうございました。
POCO のサイトを作られたんですね。
今後も機会がありましたら、
情報交換していきましょう。
ではでは。