Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 高效地存储许多组件的布尔事件的简短历史记录_Java_Performance_Boolean - Fatal编程技术网

Java 高效地存储许多组件的布尔事件的简短历史记录

Java 高效地存储许多组件的布尔事件的简短历史记录,java,performance,boolean,Java,Performance,Boolean,作为前言,我对这个问题的设计没有影响,我也不能给出很多关于技术背景的细节 假设我有很多相同类型的组件,它们定期获取布尔事件,我需要保存这些布尔事件的简短历史记录 我的一位同事使用apachecommons中的数据结构类型Map,编写了一个相当简单的实现。代码是可以工作的,但是考虑到泛型在Java中的工作方式和使用的维度,这是非常低效的,因为它存储了对两个单例布尔对象之一的引用,而不仅仅是一个位 通常有大约100K个组件,历史记录应该包含5-10个最新的布尔值(可能会发生变化,但可能不会大于10)

作为前言,我对这个问题的设计没有影响,我也不能给出很多关于技术背景的细节

假设我有很多相同类型的组件,它们定期获取布尔事件,我需要保存这些布尔事件的简短历史记录

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

通常有大约100K个组件,历史记录应该包含5-10个最新的布尔值(可能会发生变化,但可能不会大于10)。这目前意味着仅为这些历史地图分配了大约1.5GB的RAM。此外,这些更改发生得相当频繁,因此如果可能的话,提高CPU效率不会有任何影响

一个明显的变化是将历史移动到组件类中,以消除HashMap引起的开销

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

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

int历史=0;
公共无效集(整型长度,布尔型活动){
如果(活动){
历史|=1;
}
这段代码还没有经过测试。我不知道它有多高效或者是否有效,但这正是我的想法

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

如果不同组件的历史记录存储在一个连续数组中,则可以实现一些额外的保存,但我不确定如何处理一个巨大的连续位集,或者一个大字节[],其中每个字节表示一个bool历史记录,如上所述


这是一个非常特殊的问题,如果有任何建议,我都会非常高兴。

抛开我相信你会克服的比特操作,请想想效率有多高就足够了

每一个例子

class Foo {}
分配。所以如果你要介绍

class ComponentHistory {
  private final int bits;
}
这是20个字节

如果将
int
替换为
byte
,则仍然是20个字节:
byte
类型由JVM(至少)

如果您在某处定义了一个全局位数组,并从
ComponentHistory
中引用它,则引用本身位于

基本上,你赢不了:)


但请考虑:如果你使用了你已经概述过的最简单的方法,它产生了简单的可读代码,你的100K组件历史将占用2MB的RAM -从当前的1.5 GB级别节省大量。具体来说,你已经节省了1498MB。


假设你真的发明了一种笨重但有效的方法,每个历史记录只存储5位。然后你需要500Kb=60KB来存储所有历史记录。在1.5GB的基线下,你现在节省了1499.94MB。节省提高了0.1%。这有关系吗?通常情况下,我不希望在牺牲时间的同时过度优化简单性。

如果你只处理5位,你可以使用
字节而不是
int
。然后你可以
历史记录&=0b11111
来清除旧的条目。但是,在这一点上,任何优化都是最小的,可能不会影响你的性能和/或内存占用。你能给每个
组件一个索引吗
?为什么要将它们存储在
映射中?@BenjaminUrquhart感谢您的建议,但这在Java中实际上并没有什么区别(如果我错了,请纠正我)。由于内存对齐,字节成员(甚至是布尔值)无论如何都将使用32位进行存储。@Federicoperaltachaffner正如我个人所说,我不会将它们存储在映射中,这就是现在的方式。组件实际上已经被索引。我认为我现在最好的选择是使用字节数组,其中每个字节代表组件的历史。如果您已经拥有所有组件索引d(或者可以以某种方式实现),我会使用一个大的
位集来存储所有组件,也就是说,我会使用10位来表示每个组件的历史