Java中的高效LRU仿真程序

时间:2014-02-25 14:35:29

标签: java performance caching lru

我模拟LRU Web缓存。这个概念很简单:

我有一组 N个请求对象可用于缓存,我生成一个流L>对于那些以串行方式(即一个接一个)到达缓存的对象(同样类型为请求的对象)的N个随机且相同分布的请求 。我在Requests类中有一个 int字段ID ,用作区分不同请求对象的数字ID

我已将缓存实现为 ArrayList(M),其中M <&lt;&lt; Ñ

从缓存末尾插入对象(即使用 cache.add(object))以避免从一开始插入它们的处理开销(即使用cache.add(0,object))和我从缓存的开始中删除对象(即使用 cache.remove(0))。因此,缓存列表按&#34;最有价值&#34; 对象结束&##排序 34;对开始最不重要的&#34; 对象,&#34;最不重要的&#34;所有索引0 的对象(这是缓存对象,当缓存未被缓存填充时,将替换缓存对象)。

当然,我有以下操作:

  • 布尔方法查找,在缓存命中的情况下返回 true 如果缓存未命中,则返回 false

  • 从缓存末尾插入对象的方法插入

  • 方法替换,其中我从缓存中删除索引0处的项目(LRU项目)在缓存末尾插入新请求的项目

  • 方法重新排序,其中以防高速缓存如果请求的项目不在缓存列表的末尾,则将被移到那里

我使用布尔标记&#34; inCache&#34; ,以便避免查找操作中所需的for循环

问题重新排序操作,因为我必须从缓存中删除请求的对象(每次都是随机对象位于随机索引中) - 这是一个代价高昂的操作 - 然后将其插入缓存的末尾(这没问题)。

我使用技巧来提高性能,但我放弃了这个想法,因为性能提升非常小。诀窍如下:

我使用 int字段计数器到Request类,我初始化为counter = 0 每次将对象插入缓存(第一个对象除外)时,此计数器都会增加1 。因此,在任何给定的时间点,我只需从该对象的计数器值中减去位于索引0的对象的计数器值,就可以在缓存中找到随机对象的索引用纸和铅笔绘制图表,你会看到它有效!)。

这看起来不错,但是仍然存在问题:当我因为项目的缓存命中而没有放置在缓存的末尾(即缓存时)而进行缓存重新排序时。 size() - 1),然后我必须设置该对象的计数器值等于放置在缓存末尾的对象的计数器值,在缓存的末尾删除该对象,移动到那里请求对象,从该对象所在的索引循环到cache.size() - 2(即缓存列表末尾的下一个左侧索引,此处此对象所在的位置),并将所有这些计数器减少一个< / strong>即可。由于此循环用于更新计数器,代码再次变慢(我必须注意,我们正在谈论缓存大小为100,000或更多数字项目1,000,000或更多)。因此,我放弃了这个想法

我已经在某处读过,当你需要做list.remove(object)时,使用迭代器可能会带来一些性能提升。但是:

  • 我正在学习Java ,一般编程只有 3个月。我从未使用迭代器,我对此有点困惑

  • 我认为迭代器只与LinkedLists一起使用可能会提升性能的原因是它存储了该项的指针(但如果是这种情况,我不知道它在我的情况下如何帮助我)。

那么,您有任何建议吗? 迭代器解决方案是否有用?如果我该如何使用?如果,我能否以某种方式改善我已放弃的以前的想法?如果,您是否有任何其他建议

我很抱歉这个大帖子。至少我希望我已经明确说明了问题以及我采取的步骤来解决它(没有多少成功!)。

0 个答案:

没有答案