Re: List concatenation - two more methods, one truly fast
- To: mathgroup at smc.vnet.net
- Subject: [mg87805] Re: List concatenation - two more methods, one truly fast
- From: David Bailey <dave at Remove_Thisdbailey.co.uk>
- Date: Thu, 17 Apr 2008 06:58:45 -0400 (EDT)
- References: <ftv8ro$7o1$1@smc.vnet.net>
carlos at colorado.edu wrote: > As follow up, the following tests are more realistic in that p > is similar to the Graphics objects produced during a mesh > plot. The last method (table entry substitution) is about 2 orders > of magnitude faster. Unfortunately in actual plot generation I > dont known n (number of objects) in advance, so that one is out. > > ClearAll[poly,p,n]; poly={}; n=5000; SetRandom[1234]; > p[arg_]:= {Graphics[RGBColor[Random[],Random[],Random[]]], > Graphics[Polygon[{{Random[],Random[]}, > {Random[],Random[]},{Random[],Random[]}}]]}; > Print[Timing[Do[AppendTo[poly,p[i]],{i,1,n}]][[1]]]; > ClearAll[poly]; poly={}; > Print[Timing[Do[poly=Append[poly,p[i]],{i,1,n}]][[1]]]; > ClearAll[poly]; poly={}; > Print[Timing[Do[poly=Join[poly,{p[i]}],{i,1,n}]][[1]]]; > ClearAll[poly]; poly={}; > Print[Timing[Do[poly={poly,p[i]},{i,1,n}];poly=Flatten[poly]][[1]]]; > ClearAll[poly]; poly=Table[0,{n}]; > Print[Timing[Do[poly[[i]]=p[i],{i,1,n}]][[1]]; > > > 11.3361 Second > 11.3306 Second > 11.7123 Second > 7.24559 Second > 0.061505 Second > > Observation: timing of the first 4 methods is roughly O(n^2). > That would suggest that Mathematica does not implement a true > list processor in the kernel, since building a list should be O(n). > > This result is fascinating - it is reasonable that all the solutions based on appending lists work O(n^2), but the nested list approach should not behave this way. If you repeat the timing, but without defining p: n = 5000; poly = Table[0, {n}]; Print[Timing[Do[poly = {poly, p[i]}, {i, 1, n}]; poly = Flatten[poly]][[1]]]; I get 0.02 seconds rather than 11 seconds (I obviously have a slightly slower machine. This means that the time depends crucially on what you are accumulating. Consider the semantics of the operation: poly = {poly, p[i]} This will only be efficient if Mathematica 'knows' that the old value of poly is already fully evaluated. As I understand it, Mathematica does this using a hashing method, and my guess is that in this case the hash table overflows and the ever growing expression gets repeatedly evaluated - hence O(n^2). It would be nice if someone from Wolfram could comment on these timing results. Incidentally, the following method works efficiently without requiring the array size to be known in advance: n = 5000; poly = Table[0, {n}]; Print[Timing[poly = Reap[Do[Sow[p[i]], {i, 1, n}]][[2, 1]]][[1]]]; David Bailey http://www.dbaileyconsultancy.co.uk
- Follow-Ups:
- Re: Re: List concatenation - two more methods, one truly fast
- From: "W_Craig Carter" <ccarter@mit.edu>
- Re: Re: List concatenation - two more methods, one truly fast