If you know how many elements your result will have and if you can calculate your elements, then the whole Append, AppendTo, Linked-List, etc is not necessary. In the speed-test of Chris, the preallocation only works, because he knows the number of elements in advance. The access operation to datelist stands for the virtual calculation of the current element.
If the situation is like that, I would never use such an approach. A simple Table combined with a Join is the hell faster. Let me reuse Chris' code: I add the preallocation to the time measurement, because when using Append or the linked list, the memory allocation is measured too. Furthermore, I really use the resulting lists and check wether they are equal, because a clever interpreter maybe would recognize simple, useless commands an optimize these out.
Needs["PlotLegends`"]
test[n_] := Module[{
startlist = Range[1000],
datalist, joinResult, linkedResult, linkinglist, linkedlist,
preallocatedlist, linkedlisttime, preallocatedtime, count,
joinTime, preallocResult},
datalist = RandomReal[1, n*1000];
linkinglist = startlist;
{linkedlisttime, linkedResult} =
AbsoluteTiming[
Do[linkinglist = {linkinglist, datalist[[i]]}, {i,
Length[datalist]}];
linkedlist = Flatten[linkinglist]
];
count = -1;
preallocatedtime = First@AbsoluteTiming[
(preallocatedlist =
Join[startlist, ConstantArray[0, {Length[datalist]}]];
Do[preallocatedlist[[count]] = datalist[[count]];
count--, {Length[datalist]}]
)
];
{joinTime, joinResult} =
AbsoluteTiming[
Join[startlist,
Table[datalist[[i]], {i, 1, Length[datalist]}]]];
PrintTemporary[
Equal @@@ Tuples[{linkedResult, preallocatedlist, joinResult}, 2]];
{preallocatedtime, linkedlisttime, joinTime}];
results = test[#] & /@ Range[40];
ListLinePlot[Transpose[results], PlotStyle -> {Black, Gray, Red},
PlotLegend -> {"Prealloc", "Linked", "Joined"},
LegendPosition -> {1, 0}]

In my opinion, the interesting situations are, when you don't know the number of elements in advance and you have to decide ad hoc whether or not you have to append/prepend something. In those cases Reap[] and Sow[] maybe worth a look. In general I would say, AppendTo is evil and before using it, have a look at the alternatives:
n = 10.^5 - 1;
res1 = {};
t1 = First@AbsoluteTiming@Table[With[{y = Sin[x]},
If[y > 0, AppendTo[res1, y]]], {x, 0, 2 Pi, 2 Pi/n}
];
{t2, res2} = AbsoluteTiming[With[{r = Release@Table[
With[{y = Sin[x]},
If[y > 0, y, Hold@Sequence[]]], {x, 0, 2 Pi, 2 Pi/n}]},
r]];
{t3, res3} = AbsoluteTiming[Flatten@Table[
With[{y = Sin[x]},
If[y > 0, y, {}]], {x, 0, 2 Pi, 2 Pi/n}]];
{t4, res4} = AbsoluteTiming[First@Last@Reap@Table[With[{y = Sin[x]},
If[y > 0, Sow[y]]], {x, 0, 2 Pi, 2 Pi/n}]];
{res1 == res2, res2 == res3, res3 == res4}
{t1, t2, t3, t4}
Gives {5.151575, 0.250336, 0.128624, 0.148084}. The construct
Flatten@Table[ With[{y = Sin[x]}, If[y > 0, y, {}]], ...]
is luckily really readable and fast.
Remark
Be careful trying this last example at home. Here, on my Ubuntu 64bit and Mma 8.0.4 the AppendTo with n=10^5 takes 10GB of Memory. n=10^6 takes all of my RAM which is 32GB to create an array containing 15MB of data. Funny.