我有时间序列数据。内部数据的值可以是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是多少次
我面临的问题是,我在我的程序中运行了数十亿次这样的比较。完成的时间比我想要的要长得多。我知道这将需要相当长的时间才能完成,但我想知道是否有其他方法可以更快地计算它(我已经在使用多线程,我正在研究更多的变化,可能是算法,数据结构变化,开源库,等等)?
发布于 2019-01-26 08:56:32
考虑到你试图产生的大量结果,我建议你寻找微优化和分工的方法。没有什么花哨的方法可以减少操作,只要让它们变得高效即可。
因此,我建议您将字节数组转换为BitSets。您的4个计数应该通过对a.and(b) (1,1)、a.andNot(b) (1,0)、a.or(b).flip() (0,0)和a.flip().and(b) (0,1)执行cardinality()来完成。在同步工作方面,您应该将工作作为块的所有成对组合(实验此图),例如20个数组与20个数组的组合。一个足够大的工作块,足以成为真正的工作。一个足够小的模型来描述来源,并产生相当小的消息。每一项工作都应该由一个单独的worker单线程处理。仔细考虑如何存储最终数据-您的大量工作将构建该数据结构。要不惜一切代价避免的是基于散列的数据结构,它会导致您在内存中查找所有随机位置。对数据进行就地排序要好得多。
如果可以,请重点关注缓存一致性。
https://stackoverflow.com/questions/54370573
复制相似问题