Notes:
I completely overlooked the fact that rasher specified arbitrary precision input when crafting my functions. Because of this the numeric methods I used will not be as fast. However, to my surprise it seems that at least fn2 is still faster than the FoldList method on arbitrary precision data.
Timings with resets on average at about 1 in 40:
big = RandomInteger[{-1*^20, 1*^20}, 1*^6]; big = Clip[big, {-∞, 0.95*^20}, {0, 0}]; fn1[big, 0] // timeAvg fn2[big] // timeAvg
0.858 0.499
Not quite the performance on packed arrays demonstrated below, but still faster than FoldList in a number of cases.
If the resets are fairly sparse it is possible to beat the FoldList method by accumulating, then setting first zeros in the original list to appropriate negative values based on that pass, then accumulating again. As a proof of concept implemented only for resetting on zeros:
fn2[a_List] := Module[{x = a, acc = Accumulate@a, pos}, pos = Split[#, # + 1 == #2 &][[All, 1]] & @ SparseArray[Unitize@x, Automatic, 1]["AdjacencyLists"]; x[[pos]] = -Differences @ Prepend[acc[[pos]], 0]; Accumulate @ x ]
Edit: Adopting a method similar to my answer from Find continuous sequences inside a list this method is faster than the OP on rather more frequent splits as well:
fn3[a_List] := Module[{x = a, acc = Accumulate@a, pos}, pos = SparseArray[#]["AdjacencyLists"] &[ Subtract[1, Unitize@x]* Prepend[Unitize@Differences@x, 1] ]; x[[pos]] = -Differences @ Prepend[acc[[pos]], 0]; Accumulate @ x ]
I named your function fn1. The timeAvg code has been posted many times.
On a list that resets on average one in ten elements:
big = RandomInteger[9, 1*^6]; Accumulate[big] // timeAvg fn1[big, 0] // timeAvg fn2[big] // timeAvg fn3[big] // timeAvg
0.004624 0.0656 0.0748 0.02808
Here fn3 is more than twice as fast as your original.
Now with resets on average one in one thousand elements:
big = RandomInteger[999, 1*^6]; (* other lines the same *)
0.004496 0.0718 0.01248 0.0156
Here both fn2 and fn3 are several times faster than the original, but now fn3 is slightly slower than fn2. With increasingly sparse resets fn2 continues to improve over fn3.
FoldListis what I have used before. I doubt it can be beaten outside of a compiled solution, but as always I'd love to be proven wrong on such things. By the way it truly pains my terse-obsessed mind every time I seeFold[f, First[list], Rest[list]]or the equivalent written out, as I have customizedFold[f, list]to perform the same. Have you considered that? $\endgroup$Foldcustomization here: (5433867). Edit: I just updated that post to match the current customization that I use. $\endgroup$