If you need speed, you could use ugly compiled function:
equalPosInt2 = Last@Compile[{{a, _Integer, 2}, {b, _Integer, 2}},
Module[{result, dimA, dimB, n, m, eq},
result = Internal`Bag@Most@{0};
dimA = Dimensions@a;
dimB = Dimensions@b;
n = Min[Compile`GetElement[dimA, 1], Compile`GetElement[dimB, 1]];
m = Min[Compile`GetElement[dimA, 2], Compile`GetElement[dimB, 2]];
Do[
eq = True;
Do[
If[Compile`GetElement[a, i, j] =!= Compile`GetElement[b, i, j],
eq = False;
Break[];
];
,
{j, m}
];
If[eq, Internal`StuffBag[result, i]];
,
{i, n}
];
Internal`BagPart[result, All]
],
CompilationTarget -> "C", RuntimeOptions -> "Speed"
];
Basic test:
a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {1, 2, 3}};
b = {{2, 1, 3}, {4, 5, 6}, {41, 2, 0}, {1, 2, 3}};
equalPosInt2[a, b]
(* {2, 4} *)
Timings:
fraccalo[a_, b_] := Position[MapThread[Equal, {a, b}], True]
f2[a_, b_] := Position[Unitize[Subtract[a, b]].ConstantArray[1, Dimensions[a][[2]]], 0, 1]
f3[a_, b_] := SparseArray[Unitize[Unitize[Subtract[a, b]].ConstantArray[1, Dimensions[a][[2]]]], {Length[a]}, 1]["NonzeroPositions"]
kglr1[a_, b_] := Pick[Range@Length@a, Total /@ Unitize[Subtract[a, b]], 0]
kglr2[a_, b_] := Pick[Range@Length@a, Unitize[Subtract[a, b]].ConstantArray[1, Dimensions[a][[2]]], 0]
RandomSeed@12345;
{a, b} = RandomInteger[{1, 9}, {2, 1000000, 3}];
r1 = fraccalo[a, b]; // MaxMemoryUsed // RepeatedTiming (*{0.691, 280000672}*)
r2 = f2[a, b]; // MaxMemoryUsed // RepeatedTiming (*{0.0803, 64000928}*)
r3 = f3[a, b]; // MaxMemoryUsed // RepeatedTiming (*{0.048, 64001120}*)
r4 = kglr1[a, b]; // MaxMemoryUsed // RepeatedTiming (*{0.072, 56000904}*)
r5 = kglr2[a, b]; // MaxMemoryUsed // RepeatedTiming (*{0.0495, 72001232}*)
r6 = equalPosInt2[a, b]; // MaxMemoryUsed // RepeatedTiming (*{0.0054, 29928}*)
r1[[All, 1]] === r2[[All, 1]] === r3[[All, 1]] === r4 === r5 === r6
(* True *)