我有时间序列数据。内部数据的值为 1 或 0(可以是 true 或 false,或任何其他二进制表示)。
例如,我有两个时间序列数据变量:
byte[] a1 = new byte[]{1,0,0,1,0};
byte[] a2 = new byte[]{1,1,1,0,1};
我现在比较这两个数组以计算组合发生的次数:
Map<String,Integer> count = new HashMap<String,Integer>();
//all the time series arrays have the same length. In real life each would timeseries array would have a length of about 100
for(int i=0; i<ai.length(); i++){
//a1[i] and a[2] occured. If this keys exists incremnt the count by one, otherwise insert the new key
count.merge(a1[i]+":"+a2[i], 1, Integer::sum)
}
本质上,我正在寻找的输出是 a1 = 1
时 a2 = 1
和 a2 = 0
的次数>?还有,当 a1 = 0
时,a2 = 1
有多少次,a2 = 0
有多少次?
我面临的问题是我在我的程序中运行了数十亿次这样的比较。完成的时间比我想要的要长得多。我知道这需要很长时间才能完成,但想知道是否有任何其他方法可以实现它以更快地计算它(我已经在使用多线程,我正在更多地研究可能的算法、数据结构的变化改变、开源库等)?
最佳答案
鉴于您要产生大量结果,我建议您寻找微观优化和分工的方法。没有什么奇特的方法可以减少操作,只需让它们变得高效即可。
因此,我建议您将字节数组转换为 BitSet
秒。您的 4 个计数应该通过执行 cardinality()
来完成在 a.and(b)
(1,1), a.andNot(b)
(1,0), a.or(b).flip()
(0,0) 和 a.flip().and(b)
(0,1)。在同步工作方面,您应该将工作分配为(用这个图进行实验) block 的所有成对组合,比如 20 个数组和 20 个数组。足够大的工作 block 是真正的工作。一个足够小的消息来描述源并产生相当小的消息。每件工作都应该由一个 worker 单线程处理。仔细考虑如何存储最终数据——您的很多工作都将构建该数据结构。要不惜一切代价避免的事情是基于散列的数据结构,它会导致您在内存中到处寻找随机位置。就地排序数据要好得多。
如果可以,请关注缓存一致性。
关于java - 时间序列数据 - 计算两组的出现次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54370573/