3 added 1 character in body edited Mar 19 at 8:00 Henrik Schumacher 67.3k55 gold badges9696 silver badges185185 bronze badges If you need it really fast, then use Compile: n = 1000000; a = RandomReal[{-1, 1}, {n, 2, 2}]; b = RandomReal[{-1, 1}, {n, 2, 2}]; cf = Compile[{{a, _Real, 2}, {b, _Real, 2}}, b.a.b, RuntimeAttributes -> Listable, Parallelization -> True ]; MapThread[Dot, {b, a, b}]; // AbsoluteTiming // First cf[a, b]; // AbsoluteTiming // First  1.46343 0.075722 If you need it really fast then use Compile: n = 1000000; a = RandomReal[{-1, 1}, {n, 2, 2}]; b = RandomReal[{-1, 1}, {n, 2, 2}]; cf = Compile[{{a, _Real, 2}, {b, _Real, 2}}, b.a.b, RuntimeAttributes -> Listable, Parallelization -> True ]; MapThread[Dot, {b, a, b}]; // AbsoluteTiming // First cf[a, b]; // AbsoluteTiming // First  1.46343 0.075722 If you need it really fast, then use Compile: n = 1000000; a = RandomReal[{-1, 1}, {n, 2, 2}]; b = RandomReal[{-1, 1}, {n, 2, 2}]; cf = Compile[{{a, _Real, 2}, {b, _Real, 2}}, b.a.b, RuntimeAttributes -> Listable, Parallelization -> True ]; MapThread[Dot, {b, a, b}]; // AbsoluteTiming // First cf[a, b]; // AbsoluteTiming // First  1.46343 0.075722 2 edited body edited Mar 19 at 6:11 Henrik Schumacher 67.3k55 gold badges9696 silver badges185185 bronze badges OfIf you need it really fast then use Compile: n = 1000000; a = RandomReal[{-1, 1}, {n, 2, 2}]; b = RandomReal[{-1, 1}, {n, 2, 2}]; cf = Compile[{{a, _Real, 2}, {b, _Real, 2}}, b.a.b, RuntimeAttributes -> Listable, Parallelization -> True ]; MapThread[Dot, {b, a, b}]; // AbsoluteTiming // First cf[a, b]; // AbsoluteTiming // First  1.46343 0.075722 Of you need it really fast then use Compile: n = 1000000; a = RandomReal[{-1, 1}, {n, 2, 2}]; b = RandomReal[{-1, 1}, {n, 2, 2}]; cf = Compile[{{a, _Real, 2}, {b, _Real, 2}}, b.a.b, RuntimeAttributes -> Listable, Parallelization -> True ]; MapThread[Dot, {b, a, b}]; // AbsoluteTiming // First cf[a, b]; // AbsoluteTiming // First  1.46343 0.075722 If you need it really fast then use Compile: n = 1000000; a = RandomReal[{-1, 1}, {n, 2, 2}]; b = RandomReal[{-1, 1}, {n, 2, 2}]; cf = Compile[{{a, _Real, 2}, {b, _Real, 2}}, b.a.b, RuntimeAttributes -> Listable, Parallelization -> True ]; MapThread[Dot, {b, a, b}]; // AbsoluteTiming // First cf[a, b]; // AbsoluteTiming // First  1.46343 0.075722 1 answered Mar 18 at 23:36 Henrik Schumacher 67.3k55 gold badges9696 silver badges185185 bronze badges Of you need it really fast then use Compile: n = 1000000; a = RandomReal[{-1, 1}, {n, 2, 2}]; b = RandomReal[{-1, 1}, {n, 2, 2}]; cf = Compile[{{a, _Real, 2}, {b, _Real, 2}}, b.a.b, RuntimeAttributes -> Listable, Parallelization -> True ]; MapThread[Dot, {b, a, b}]; // AbsoluteTiming // First cf[a, b]; // AbsoluteTiming // First  1.46343 0.075722