This question reminded me something I did some time ago when I was computing Lyapunov exponents of maps, i.e. discrete dynamical systems. Let me share it here.
What I needed was to compute the matrix product successively from the end (I wanted to be able to plot a convergence plot), i.e. have access to data[[5]]
, data[[4]].data[[5]]
etc. I had $10^4$ matrices in one go and repeated it for $10^5$ realisations, so forming a Table
explicitly was numerically very expensive. So I came up with this solution:
v[1] = Last[data];
v[n_] := v[n] = data[[Length[data] - (n - 1)]].v[n - 1]
which, even when Length@data
is huge, gives almost instant access to any step.
While this in fact gives an answer to your question, as v[Length@data]
will give the same result as Dot@@data
, it is of course less elegant and efficient than Dot@@data
. But in case you would like to look into the intermediate steps (noting that the multiplications are done starting from the end of the matrices stored in data
) this will provide them.
EDIT: In case one wants to access the intermediate steps starting from the beginning of data
, i.e. to access the accumulative dot product:
p[1] = First[data];
p[n_] := p[n] = p[n - 1].data[[n]]