如何计算相同的字节数

时间:2011-10-06 20:33:48

标签: java algorithm

我有两个长字节数组,我需要计算相应位置上的字节数是否相同。我的解决方案(在JAVA中)如下:

    int sum = 0;
    for(int i = 0;i < t.length;i++)
      if (t[i] == spb[i])
        sum++;

由于我的程序的这部分花费了大量时间,我想知道我是否可以更快地完成这个任务

显然两个数组的长度相同

4 个答案:

答案 0 :(得分:6)

如果数组很长,你可以使用多个并发线程来计算数组部分的部分和,然后总结部分总和。

答案 1 :(得分:5)

不,你基本上做的是正确的事情(至少对于一个线程来说 - 西蒙的使用多线程的想法很好)。这需要多长时间,阵列有多长?它应该很快。

可能能够通过在字节数组周围创建ByteBuffer来加速它,然后使用asLongBuffer创建一个LongBuffer再次包装它。然后,您可以一次检查8个字节(如长),​​仅在long比较返回false时检查单个字节。这会是一个非常复杂的代码 - 而且我不会在所有中惊讶地发现它实际上要慢得多。

答案 2 :(得分:1)

除了使用先前建议的“并发线程来计算数组部分的部分和”方法之外(我将在后面的段落中进行评论),您可以使用两种简单的技术来加速循环:(1){ {1}}三级运算符而不是?:测试,以及(2)循环展开。

在我的旧2GHz系统上,使用gcj java编译器,每种技术都提供了几个百分点的加速。您在机器上获得的改进(如果有的话)可能是编译器或jvm相关的。

代码示例:

if

转到

    if (t[i] == spb[i]) sum++;

    sum += t[i] == spb[i] ? 1 : 0;

转到(例如)

    public static int counts (byte[] A, byte[] B) {
       int i, count, L=A.length;
       for (count=i=0; i<L; i++)
          count += A[i]==B[i] ? 1 : 0;
       return count;
    }

循环展开可以使用 public static int counts (byte[] A, byte[] B) { final int S=8; int i, count, L=A.length-S; for(count=i=0; i<L; i+=S) { count += A[i+0]==B[i+0] ? 1 : 0; count += A[i+1]==B[i+1] ? 1 : 0; count += A[i+2]==B[i+2] ? 1 : 0; count += A[i+3]==B[i+3] ? 1 : 0; count += A[i+4]==B[i+4] ? 1 : 0; count += A[i+5]==B[i+5] ? 1 : 0; count += A[i+6]==B[i+6] ? 1 : 0; count += A[i+7]==B[i+7] ? 1 : 0; } for (; i<L+S; ++i) count += A[i]==B[i] ? 1 : 0; return count; } ,其值大于或小于上面显示的S。但是,在我运行的测试中,S=8S=16相比几乎没有任何改进。一些采样时序,202MB阵列:

S=8

在此次运行中,E。时间比A小6%,而F.和G.比E小8%,比A小14%。(其他时间,未显示,验证前一个回答声称“请求对象的字段(t.length)比局部变量花费更多的时间”,这是无关紧要的。)

关于并发线程的使用:假设您使用三个线程。在其他方法中,您可以让线程A. 51094384 matches in 3.421857144 sec. (original loop) E. 51094384 matches in 3.212364808 sec. (use ?: value) F. 51094384 matches in 2.953596272 sec. (?: + S=8 unroll) G. 51094384 matches in 2.949984214 sec. (?: + S=16 unroll) 处理每个数组的i'三分之一中的连续字节,或者您可以让线程i处理每个第三个字节,即带有字节的字节index mod 3 = i。值得对执行时间的差异进行基准测试。我希望它在不同的机器上会有所不同,具体取决于缓存大小和制度。

答案 3 :(得分:0)

int sum = 0;
for(int i = t.length - 1;i >= 0 ;i--)
if (t[i] == spb[i])
    sum++;

原则上,请求对象的字段(t.length)比局部变量(i)花费更多的时间。如果从最后一个迭代到第一个,那么最昂贵的指令只执行一次。