For Integer data we also could write:
Tr @ Unitize @ BitXor[ab, ac]
1
For Real data we can use the slightly slower but also shorter:
Tr @ Unitize[ab - ac]
Blackbird challenged me to provide a method that works on all input types. My approach is to select between methods depending on data.
diff[a__?(VectorQ[#, IntegerQ] &)] := Tr @ Unitize @ BitXor @ a
diff[a__?(VectorQ[#, NumericQ] &)] := Tr @ Unitize @ Subtract @ a
diff[a_, b_] := HammingDistance[a, b]
Timings for some of the methods posted so far (search the site for timeAvg
):
{ab, ac} = List @@ RandomInteger[2, {2, 250000}]; (* List @@ to prevent unpacking *)
HammingDistance[ab, ac] // timeAvg
Count[MapThread[Equal, {ab, ac}], False] // timeAvg
Tr @ Unitize @ BitXor[ab, ac] // timeAvg
diff[ab, ac] // timeAvg
0.009984
0.05428
0.0005488
0.0005744
Now with Real data:
{ab, ac} = N /@ {ab, ac};
HammingDistance[ab, ac] // timeAvg
Count[MapThread[Equal, {ab, ac}], False] // timeAvg
Tr @ Unitize[ab - ac] // timeAvg
diff[ab, ac] // timeAvg
0.01872
0.0748
0.00312
0.0021728
(I learned something from this test: Subtract[a,b]
is faster than a-b
on packed reals.)
Now something unpackable:
{ab, ac} = RandomChoice[CharacterRange["a", "z"], {2, 250000}];
HammingDistance[ab, ac] // timeAvg
Count[MapThread[Equal, {ab, ac}], False] // timeAvg
diff[ab, ac] // timeAvg
0.005488
0.0524
0.005496