首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有效地存储许多组件的布尔事件的简短历史

有效地存储许多组件的布尔事件的简短历史
EN

Stack Overflow用户
提问于 2019-08-16 01:37:37
回答 1查看 73关注 0票数 2

作为开场白-我对这个问题的设计没有任何影响,我也不能给出更多关于技术背景的细节。

假设我有许多相同类型的组件定期获得布尔事件-我需要保存这些布尔事件的简短历史记录。

我的一个同事使用Map<Component, CircularFifoQueue<Boolean>>类型编写了一个相当简单的实现,CircularFifoQueue是来自Apache Commons的数据结构。代码可以工作,但是考虑到泛型在Java中的工作方式和所使用的维度,这是非常低效的,因为它存储了对两个单例布尔对象之一的引用,而不是只存储一个位。

一般来说,大约有100K个组件,历史记录应该包含5-10个最近的布尔值(可能会发生变化,但可能不会大于10)。这意味着目前仅为这些历史地图就分配了大约1.5 of的RAM。此外,这些更改经常发生,因此如果可能的话,提高CPU效率也不会有什么坏处。

一个明显的变化是将历史记录移到Component类中,以消除由HashMap引起的开销。

更复杂的问题是如何有效地存储最后几个布尔值。一种可能的方法是使用BitSets,但是由于那些使用long[]作为底层数据结构的人,我怀疑这是否是存储本质上是5位的内容的最有效的方式。

另一种选择是直接使用整数并将值移位,作为删除旧条目的一种方式。所以基本上

代码语言:javascript
复制
int history = 0;
public void set(int length, boolean active){
   if(active) {
      history |= 1 << length;
   } else {
      history &= ~(1 << length);
   }
   // shift one to the right to remove oldest entry
   history = history >> 1;
}

就在我的脑海里。这段代码是未经测试的。我不知道它的效率如何,也不知道它是否有效,但这就是我的想法。

但与使用5位内存存储5位数据的最佳情况相比,这仍然会导致相当大的开销。

如果将不同组件的历史存储在一个连续的数组中,可以实现一些额外的节省,但是我不确定如何处理任何一个巨大的连续的BitSet。或者可替换地,一个较大的byte[],其中每个字节表示如上所述的一个布尔历史。

这是一个奇怪的具体问题,我真的很高兴有任何建议。

EN

回答 1

Stack Overflow用户

发布于 2019-08-16 02:41:54

抛开我相信你会克服的位操作,请想一想,效率如何才够有效。

的每个实例

代码语言:javascript
复制
class Foo {}

分配16 bytes。所以如果你要介绍

代码语言:javascript
复制
class ComponentHistory {
  private final int bits;
}

这是20个字节。

如果将int替换为byte,仍然是20个字节:byte类型至少是padded to 4 bytes by JVM。

如果您在某个地方定义了一个全局位数组并从ComponentHistory引用它,则引用本身位于least 4 bytes

基本上,你赢不了:)

但考虑到这一点:如果您采用您已经概述的最简单的方法,即生成简单的可读代码,那么您的100K组件历史将占用2MB的RAM -与您当前1.5 go的级别相比节省了大量的内存。具体地说,您节省了1498MB。

假设您确实发明了一种繁琐但有效的方法,即每个历史记录只存储5位。然后,您需要500Kb = 60KB来存储所有历史记录。使用1.5 of的基线,您现在节省了1499.94MB。节省了0.1%的。这有什么关系吗?通常情况下,我不希望在这里过度优化,同时牺牲简单性。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57513825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档