我有时间序列数据。其中的数据值为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
是多少次?
我面临的问题是我正在程序中进行数十亿次这样的比较。完成时间比我想要的要长得多。我了解完成此操作的性质将花费很长时间,但我想知道是否还有其他方法可以实现此功能以更快地进行计算(我已经在使用多线程,我正在研究可能的算法,数据结构的变化变化,开源库等)?
答案 0 :(得分:2)
鉴于您试图产生大量结果,我建议您寻找微优化和划分工作的方法。没有什么花哨的方法可以减少操作,而只需进行高效的操作即可。
因此,我建议您将字节数组转换为BitSet
。您应通过对cardinality()
(1,1),a.and(b)
(1,0),a.andNot(b)
(0,0)和{{ 1}}(0,1)。在同步工作方面,您应该按(该图的实验)的块的所有成对组合说20个数组和20个数组来分发工作。足够大的工作量才能成为实际的工作。足够小以描述来源,并产生相当小的消息。每项工作应由一名工人进行单线程处理。仔细考虑如何存储最终数据-您的许多工作将建立该数据结构。不惜一切代价避免的事情是基于哈希的数据结构,该结构使您要在内存中的所有随机位置进行查找。更好地对数据进行排序。
如果可以,请关注缓存一致性。