Performance comparison
Here is a performance comparison of all methods given in the order of their posting.
Bill's code is not self-contained so I shall use:
bill[a_, b_] :=
Module[{h, list = b},
Map[(h = Take[list, Length[#]]; list = Drop[list, Length[#]]; # + h) &, a]
]
The other functions for ease of execution:
add[a_List, b_List] := a + dynP[b, Length /@ a]
listAdd[structured_, flat_] :=
Module[{i = 1}, Function[elm, elm + flat[[i++]], {Listable}][structured]]
raggedMap = Internal`PartitionRagged[#1[Flatten[#2], #3], Length /@ #2] &;
listAdd1[structured_, flat_] := Module[{cnt = 1, f}, f = Function[x, x + flat[[cnt++]]];
Map[f, structured, {-1}]]
deFlatten[flat_, reference_] :=
Module[{cnt = 1}, Replace[reference, elem_ :> flat[[cnt++]], {-1}]]
listAdd2[structured_, flat_] := deFlatten[Flatten[structured] + flat, structured]
Yi Wang's listAdd3
threw errors so I did not include it in this test.
Generating code for two lists of the like type (Integer) with short sublists:
Needs["GeneralUtilities`"]
a = RandomInteger[9, #] & /@ RandomInteger[{1, 9}, 5000];
b = RandomInteger[9, Length@Flatten@a];
bill[a, b] // AccurateTiming
add[a, b] // AccurateTiming
listAdd[a, b] // AccurateTiming
raggedMap[Plus, a, b] // AccurateTiming
listAdd1[a, b] // AccurateTiming
listAdd2[a, b] // AccurateTiming
Like-types and long sublists:
a = RandomInteger[9, #] & /@ RandomInteger[{1, 500}, 500];
b = RandomInteger[9, Length@Flatten@a];
Unlike types and short sublists:
a = RandomInteger[9, #] & /@ RandomInteger[{1, 9}, 5000];
b = RandomChoice[{"a", "b", "c"}, Length@Flatten@a];
Unlike types and long sublists:
a = RandomInteger[9, #] & /@ RandomInteger[{1, 500}, 500];
b = RandomChoice[{"a", "b", "c"}, Length@Flatten@a];
A table of results:
