Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

root/trunk/tango/util/container/LinkedList.d

Revision 5416, 35.7 kB (checked in by kris, 2 years ago)

made the default allocator faster, and hid the implementation from the containers. Use the new cache() method instead for configuring how containers pre-allocate.

  • Property svn:eol-style set to native
Line 
1 /*******************************************************************************
2
3         copyright:      Copyright (c) 2008 Kris Bell. All rights reserved
4
5         license:        BSD style: $(LICENSE)
6
7         version:        Apr 2008: Initial release
8
9         authors:        Kris
10
11         Since:          0.99.7
12
13         Based upon Doug Lea's Java collection package
14
15 *******************************************************************************/
16
17 module tango.util.container.LinkedList;
18
19 private import  tango.util.container.Slink;
20
21 public  import  tango.util.container.Container;
22
23 private import tango.util.container.model.IContainer;
24
25 /*******************************************************************************
26
27         List of singly-linked values
28
29         ---
30     Iterator iterator ()
31         int opApply (int delegate(ref V value) dg)
32
33         V head ()
34         V tail ()
35         V head (V value)
36         V tail (V value)
37         V removeHead ()
38         V removeTail ()
39
40         bool contains (V value)
41         size_t first (V value, size_t startingIndex = 0)
42         size_t last (V value, size_t startingIndex = 0)
43
44         LinkedList add (V value)
45         LinkedList prepend (V value)
46         size_t prepend (IContainer!(V) e)
47         LinkedList append (V value)
48         size_t append (IContainer!(V) e)
49         LinkedList addAt (size_t index, V value)
50         size_t addAt (size_t index, IContainer!(V) e)
51
52         V get (size_t index)
53         bool take (ref V v)
54         size_t remove (V value, bool all)
55         bool removeAt (size_t index)
56         size_t removeRange (size_t fromIndex, size_t toIndex)
57         size_t replace (V oldElement, V newElement, bool all)
58         bool replaceAt (size_t index, V value)
59
60         LinkedList clear ()
61         LinkedList reset ()
62
63         LinkedList subset (size_t from, size_t length = size_t.max)
64         LinkedList dup ()
65
66         size_t size ()
67         bool isEmpty ()
68         V[] toArray (V[] dst)
69         LinkedList sort (Compare!(V) cmp)
70         LinkedList check ()
71         ---
72
73 *******************************************************************************/
74
75 class LinkedList (V, alias Reap = Container.reap,
76                      alias Heap = Container.DefaultCollect)
77                      : IContainer!(V)
78 {
79         // use this type for Allocator configuration
80         private alias Slink!(V) Type;
81        
82         private alias Type*     Ref;
83         private alias V*        VRef;
84
85         private alias Heap!(Type) Alloc;
86
87         // number of elements contained
88         private size_t          count;
89
90         // configured heap manager
91         private Alloc           heap;
92        
93         // mutation tag updates on each change
94         private size_t          mutation;
95
96         // head of the list. Null if empty
97         private Ref             list;
98
99         /***********************************************************************
100
101                 Create a new empty list
102
103         ***********************************************************************/
104
105         this ()
106         {
107                 this (null, 0);
108         }
109
110         /***********************************************************************
111
112                 Special version of constructor needed by dup
113
114         ***********************************************************************/
115
116         protected this (Ref l, size_t c)
117         {
118                 list = l;
119                 count = c;
120         }
121
122         /***********************************************************************
123
124                 Clean up when deleted
125
126         ***********************************************************************/
127
128         ~this ()
129         {
130                 reset;
131         }
132
133         /***********************************************************************
134
135                 Return a generic iterator for contained elements
136                 
137         ***********************************************************************/
138
139         final Iterator iterator ()
140         {
141                 Iterator i = void;
142                 i.mutation = mutation;
143                 i.node = list ? *(i.hook = &list) : null;
144                 i.prior = null;
145                 i.owner = this;
146                 return i;
147         }
148
149         /***********************************************************************
150
151                 Configure the assigned allocator with the size of each
152                 allocation block (number of nodes allocated at one time)
153                 and the number of nodes to pre-populate the cache with.
154                 
155                 Time complexity: O(n)
156
157         ***********************************************************************/
158
159         final LinkedList cache (size_t chunk, size_t count=0)
160         {
161                 heap.config (chunk, count);
162                 return this;
163         }
164
165         /***********************************************************************
166
167
168         ***********************************************************************/
169
170         final int opApply (int delegate(ref V value) dg)
171         {
172                 return iterator.opApply (dg);
173         }
174
175         /***********************************************************************
176
177                 Return the number of elements contained
178                 
179         ***********************************************************************/
180
181         final size_t size ()
182         {
183                 return count;
184         }
185
186         /***********************************************************************
187
188                 Build an independent copy of the list.
189                 The elements themselves are not cloned
190
191         ***********************************************************************/
192
193         final LinkedList dup ()
194         {
195                 return new LinkedList!(V, Reap, Heap) (list ? list.copy(&heap.allocate) : null, count);
196         }
197
198         /***********************************************************************
199
200                 Time complexity: O(n)
201
202         ***********************************************************************/
203
204         final bool contains (V value)
205         {
206                 if (count is 0)
207                     return false;
208
209                 return list.find(value) !is null;
210         }
211
212         /***********************************************************************
213
214                  Time complexity: O(1)
215
216         ***********************************************************************/
217
218         final V head ()
219         {
220                 return firstCell.value;
221         }
222
223         /***********************************************************************
224
225                  Time complexity: O(n)
226
227         ***********************************************************************/
228
229         final V tail ()
230         {
231                 return lastCell.value;
232         }
233
234         /***********************************************************************
235
236                  Time complexity: O(n)
237
238         ***********************************************************************/
239
240         final V get (size_t index)
241         {
242                 return cellAt(index).value;
243         }
244
245         /***********************************************************************
246
247                  Time complexity: O(n)
248                  Returns size_t.max if no element found.
249
250         ***********************************************************************/
251
252         final size_t first (V value, size_t startingIndex = 0)
253         {
254                 if (list is null || startingIndex >= count)
255                     return size_t.max;
256
257                 if (startingIndex < 0)
258                     startingIndex = 0;
259
260                 auto p = list.nth (startingIndex);
261                 if (p)
262                    {
263                    auto i = p.index (value);
264                    if (i >= 0)
265                        return i + startingIndex;
266                    }
267                 return size_t.max;
268         }
269
270         /***********************************************************************
271
272                  Time complexity: O(n)
273                  Returns size_t.max if no element found.
274
275         ***********************************************************************/
276
277         final size_t last (V value, size_t startingIndex = 0)
278         {
279                 if (list is null)
280                     return size_t.max;
281
282                 auto i = 0;
283                 if (startingIndex >= count)
284                     startingIndex = count - 1;
285
286                 auto index = size_t.max;
287                 auto p = list;
288                 while (i <= startingIndex && p)
289                       {
290                       if (p.value == value)
291                           index = i;
292                       ++i;
293                       p = p.next;
294                       }
295                 return index;
296         }
297
298         /***********************************************************************
299
300                  Time complexity: O(length)
301
302         ***********************************************************************/
303
304         final LinkedList subset (size_t from, size_t length = size_t.max)
305         {
306                 Ref newlist = null;
307
308                 if (length > 0)
309                    {
310                    auto p = cellAt (from);
311                    auto current = newlist = heap.allocate.set (p.value, null);
312          
313                    for (auto i = 1; i < length; ++i)
314                         if ((p = p.next) is null)
315                              length = i;
316                         else
317                            {
318                            current.attach (heap.allocate.set (p.value, null));
319                            current = current.next;
320                            }
321                    }
322
323                 return new LinkedList (newlist, length);
324         }
325
326         /***********************************************************************
327
328                  Time complexity: O(n)
329
330         ***********************************************************************/
331
332         final LinkedList clear ()
333         {
334                 return clear (false);
335         }
336
337         /***********************************************************************
338
339                 Reset the HashMap contents and optionally configure a new
340                 heap manager. We cannot guarantee to clean up reconfigured
341                 allocators, so be sure to invoke reset() before discarding
342                 this class
343
344                 Time complexity: O(n)
345                 
346         ***********************************************************************/
347
348         final LinkedList reset ()
349         {
350                 return clear (true);
351         }
352
353         /***********************************************************************
354         
355                 Takes the first value on the list
356
357                 Time complexity: O(1)
358
359         ***********************************************************************/
360
361         final bool take (ref V v)
362         {
363                 if (count)
364                    {
365                    v = head;
366                    removeHead;
367                    return true;
368                    }
369                 return false;
370         }
371
372         /***********************************************************************
373
374                 Uses a merge-sort-based algorithm.
375
376                 Time complexity: O(n log n)
377
378         ***********************************************************************/
379
380         final LinkedList sort (Compare!(V) cmp)
381         {
382                 if (list)
383                    {
384                    list = Ref.sort (list, cmp);
385                    mutate;
386                    }
387                 return this;
388         }
389
390         /***********************************************************************
391
392                 Time complexity: O(1)
393
394         ***********************************************************************/
395
396         final LinkedList add (V value)
397         {
398                 return prepend (value);
399         }
400
401         /***********************************************************************
402
403                 Time complexity: O(1)
404
405         ***********************************************************************/
406
407         final LinkedList prepend (V value)
408         {
409                 list = heap.allocate.set (value, list);
410                 increment;
411                 return this;
412         }
413
414         /***********************************************************************
415
416                 Time complexity: O(n)
417
418         ***********************************************************************/
419
420         final size_t remove (V value, bool all = false)
421         {
422                 auto c = count;
423                 if (c)
424                    {
425                    auto p = list;
426                    auto trail = p;
427
428                    while (p)
429                          {
430                          auto n = p.next;
431                          if (p.value == value)
432                             {
433                             decrement (p);
434                             if (p is list)
435                                {
436                                list = n;
437                                trail = n;
438                                }
439                             else
440                                trail.next = n;
441
442                             if (!all || count is 0)
443                                  break;
444                             else
445                                p = n;
446                             }
447                          else
448                             {
449                             trail = p;
450                             p = n;
451                             }
452                          }
453                    }
454                 return c - count;
455         }
456
457         /***********************************************************************
458
459                 Time complexity: O(n)
460
461         ***********************************************************************/
462
463         final size_t replace (V oldElement, V newElement, bool all = false)
464         {
465                 size_t c;
466                 if (count && oldElement != newElement)
467                    {
468                    auto p = list.find (oldElement);
469                    while (p)
470                          {
471                          ++c;
472                          mutate;
473                          p.value = newElement;
474                          if (!all)
475                               break;
476                          p = p.find (oldElement);
477                          }
478                    }
479                 return c;
480         }
481
482         /***********************************************************************
483
484                  Time complexity: O(1)
485
486         ***********************************************************************/
487
488         final V head (V value)
489         {
490                 auto cell = firstCell;
491                 auto v = cell.value;
492                 cell.value = value;
493                 mutate;
494                 return v;
495         }
496
497         /***********************************************************************
498
499                  Time complexity: O(1)
500
501         ***********************************************************************/
502
503         final V removeHead ()
504         {
505                 auto p = firstCell;
506                 auto v = p.value;
507                 list = p.next;
508                 decrement (p);
509                 return v;
510         }
511
512         /***********************************************************************
513
514                  Time complexity: O(n)
515
516         ***********************************************************************/
517
518         final LinkedList append (V value)
519         {
520                 if (list is null)
521                     prepend (value);
522                 else
523                    {
524                    list.tail.next = heap.allocate.set (value, null);
525                    increment;
526                    }
527                 return this;
528         }
529
530         /***********************************************************************
531
532                  Time complexity: O(n)
533
534         ***********************************************************************/
535
536         final V tail (V value)
537         {
538                 auto p = lastCell;
539                 auto v = p.value;
540                 p.value = value;
541                 mutate;
542                 return v;
543         }
544
545         /***********************************************************************
546
547                  Time complexity: O(n)
548
549         ***********************************************************************/
550
551         final V removeTail ()
552         {
553                 if (firstCell.next is null)
554                     return removeHead;
555
556                 auto trail = list;
557                 auto p = trail.next;
558
559                 while (p.next)
560                       {
561                       trail = p;
562                       p = p.next;
563                       }
564                 trail.next = null;
565                 auto v = p.value;
566                 decrement (p);
567                 return v;
568         }
569
570         /***********************************************************************
571
572                 Time complexity: O(n)
573
574         ***********************************************************************/
575
576         final LinkedList addAt (size_t index, V value)
577         {
578                 if (index is 0)
579                     prepend (value);
580                 else
581                    {
582                    cellAt(index - 1).attach (heap.allocate.set(value, null));
583                    increment;
584                    }
585                 return this;
586         }
587
588         /***********************************************************************
589
590                  Time complexity: O(n)
591
592         ***********************************************************************/
593
594         final LinkedList removeAt (size_t index)
595         {
596                 if (index is 0)
597                     removeHead;
598                 else
599                    {
600                    auto p = cellAt (index - 1);
601                    auto t = p.next;
602                    p.detachNext;
603                    decrement (t);
604                    }
605                 return this;
606         }
607
608         /***********************************************************************
609
610                  Time complexity: O(n)
611
612         ***********************************************************************/
613
614         final LinkedList replaceAt (size_t index, V value)
615         {
616                 cellAt(index).value = value;
617                 mutate;
618                 return this;
619         }
620
621         /***********************************************************************
622
623                  Time complexity: O(number of elements in e)
624
625         ***********************************************************************/
626
627         final size_t prepend (IContainer!(V) e)
628         {
629                 auto c = count;
630                 splice_ (e, null, list);
631                 return count - c;
632         }
633
634         /***********************************************************************
635
636                  Time complexity: O(n + number of elements in e)
637
638         ***********************************************************************/
639
640         final size_t append (IContainer!(V) e)
641         {
642                 auto c = count;
643                 if (list is null)
644                     splice_ (e, null, null);
645                 else
646                    splice_ (e, list.tail, null);
647                 return count - c;
648         }
649
650         /***********************************************************************
651
652                 Time complexity: O(n + number of elements in e)
653
654         ***********************************************************************/
655
656         final size_t addAt (size_t index, IContainer!(V) e)
657         {
658                 auto c = count;
659                 if (index is 0)
660                     splice_ (e, null, list);
661                 else
662                    {
663                    auto p = cellAt (index - 1);
664                    splice_ (e, p, p.next);
665                    }
666                 return count - c;
667         }
668
669         /***********************************************************************
670
671                 Time complexity: O(n)
672
673         ***********************************************************************/
674
675         final size_t removeRange (size_t fromIndex, size_t toIndex)
676         {
677                 auto c = count;
678                 if (fromIndex <= toIndex)
679                    {
680                    if (fromIndex is 0)
681                       {
682                       auto p = firstCell;
683                       for (size_t i = fromIndex; i <= toIndex; ++i)
684                            p = p.next;
685                       list = p;
686                       }
687                    else
688                       {
689                       auto f = cellAt (fromIndex - 1);
690                       auto p = f;
691                       for (size_t i = fromIndex; i <= toIndex; ++i)
692                            p = p.next;
693                       f.next = p.next;
694                       }
695
696                   count -= (toIndex - fromIndex + 1);
697                   mutate;
698                   }
699                 return c - count;
700         }
701
702         /***********************************************************************
703
704                 Copy and return the contained set of values in an array,
705                 using the optional dst as a recipient (which is resized
706                 as necessary).
707
708                 Returns a slice of dst representing the container values.
709                 
710                 Time complexity: O(n)
711                 
712         ***********************************************************************/
713
714         final V[] toArray (V[] dst = null)
715         {
716                 if (dst.length < count)
717                     dst.length = count;
718
719                 size_t i = 0;
720                 foreach (v; this)
721                          dst[i++] = v;
722                 return dst [0 .. count];                       
723         }
724
725         /***********************************************************************
726
727                 Is this container empty?
728                 
729                 Time complexity: O(1)
730                 
731         ***********************************************************************/
732
733         final bool isEmpty ()
734         {
735                 return count is 0;
736         }
737
738         /***********************************************************************
739
740         ***********************************************************************/
741
742         final LinkedList check ()
743         {
744                 assert(((count is 0) is (list is null)));
745                 assert((list is null || list.count is size));
746
747                 size_t c = 0;
748                 for (Ref p = list; p; p = p.next)
749                     {
750                     assert(instances(p.value) > 0);
751                     assert(contains(p.value));
752                     ++c;
753                     }
754                 assert(c is count);
755                 return this;
756         }
757
758         /***********************************************************************
759
760                  Time complexity: O(n)
761
762         ***********************************************************************/
763
764         private size_t instances (V value)
765         {
766                 if (count is 0)
767                     return 0;
768
769                 return list.count (value);
770         }
771
772         /***********************************************************************
773
774         ***********************************************************************/
775
776         private Ref firstCell ()
777         {
778                 checkIndex (0);
779                 return list;
780         }
781
782         /***********************************************************************
783
784         ***********************************************************************/
785
786         private Ref lastCell ()
787         {
788                 checkIndex (0);
789                 return list.tail;
790         }
791
792         /***********************************************************************
793
794         ***********************************************************************/
795
796         private Ref cellAt (size_t index)
797         {
798                 checkIndex (index);
799                 return list.nth (index);
800         }
801
802         /***********************************************************************
803
804         ***********************************************************************/
805
806         private void checkIndex (size_t index)
807         {
808                 if (index >= count)
809                     throw new Exception ("out of range");
810         }
811
812         /***********************************************************************
813
814                 Splice elements of e between hd and tl. If hd
815                 is null return new hd
816
817                 Returns the count of new elements added
818
819         ***********************************************************************/
820
821         private void splice_ (IContainer!(V) e, Ref hd, Ref tl)
822         {
823                 Ref newlist = null;
824                 Ref current = null;
825
826                 foreach (v; e)
827                         {
828                         increment;
829
830                         auto p = heap.allocate.set (v, null);
831                         if (newlist is null)
832                             newlist = p;
833                         else
834                            current.next = p;
835                         current = p;
836                         }
837
838                 if (current)
839                    {
840                    current.next = tl;
841
842                    if (hd is null)
843                        list = newlist;
844                    else
845                       hd.next = newlist;
846                    }
847         }
848
849         /***********************************************************************
850
851                  Time complexity: O(n)
852
853         ***********************************************************************/
854
855         private LinkedList clear (bool all)
856         {
857                 mutate;
858
859                 // collect each node if we can't collect all at once
860                 if (heap.collect(all) is false && count)
861                    {
862                    auto p = list;
863                    while (p)
864                          {
865                          auto n = p.next;
866                          decrement (p);
867                          p = n;
868                          }
869                    }
870        
871                 list = null;
872                 count = 0;
873                 return this;
874         }
875
876         /***********************************************************************
877
878                 new element was added
879                 
880         ***********************************************************************/
881
882         private void increment ()
883         {
884                 ++mutation;
885                 ++count;
886         }
887        
888         /***********************************************************************
889
890                 element was removed
891                 
892         ***********************************************************************/
893
894         private void decrement (Ref p)
895         {
896                 Reap (p.value);
897                 heap.collect (p);
898                 ++mutation;
899                 --count;
900         }
901        
902         /***********************************************************************
903
904                 set was changed
905                 
906         ***********************************************************************/
907
908         private void mutate ()
909         {
910                 ++mutation;
911         }
912
913         /***********************************************************************
914
915                 List iterator
916
917         ***********************************************************************/
918
919         private struct Iterator
920         {
921                 Ref             node;
922                 Ref*            hook,
923                                 prior;
924                 LinkedList      owner;
925                 size_t          mutation;
926
927                 /***************************************************************
928
929                         Did the container change underneath us?
930
931                 ***************************************************************/
932
933                 bool valid ()
934                 {
935                         return owner.mutation is mutation;
936                 }               
937
938                 /***************************************************************
939
940                         Accesses the next value, and returns false when
941                         there are no further values to traverse
942
943                 ***************************************************************/
944
945                 bool next (ref V v)
946                 {
947                         auto n = next;
948                         return (n) ? v = *n, true : false;
949                 }
950                
951                 /***************************************************************
952
953                         Return a pointer to the next value, or null when
954                         there are no further values to traverse
955
956                 ***************************************************************/
957
958                 V* next ()
959                 {
960                         V* r;
961                         if (node)
962                            {
963                            prior = hook;
964                            r = &node.value;
965                            node = *(hook = &node.next);
966                            }
967                         return r;
968                 }
969
970                 /***************************************************************
971
972                         Insert a new value before the node about to be
973                         iterated (or after the node that was just iterated).
974
975                 ***************************************************************/
976
977                 void insert(V value)
978                 {
979                         // insert a node previous to the node that we are
980                         // about to iterate.
981                         *hook = owner.heap.allocate.set(value, *hook);
982                         node = *hook;
983                         next();
984
985                         // update the count of the owner, and ignore this
986                         // change in the mutation.
987                         owner.increment;
988                         mutation++;
989                 }
990
991                 /***************************************************************
992
993                         Insert a new value before the value that was just
994                         iterated.
995
996                         Returns true if the prior node existed and the
997                         insertion worked.  False otherwise.
998
999                 ***************************************************************/
1000
1001                 bool insertPrior(V value)
1002                 {
1003                     if(prior)
1004                     {
1005                         // insert a node previous to the node that we just
1006                         // iterated.
1007                         *prior = owner.heap.allocate.set(value, *prior);
1008                         prior = &(*prior).next;
1009
1010                         // update the count of the owner, and ignore this
1011                         // change in the mutation.
1012                         owner.increment;
1013                         mutation++;
1014                         return true;
1015                     }
1016                     return false;
1017                 }
1018
1019                 /***************************************************************
1020
1021                         Foreach support
1022
1023                 ***************************************************************/
1024
1025                 int opApply (int delegate(ref V value) dg)
1026                 {
1027                         int result;
1028
1029                         auto n = node;
1030                         while (n)
1031                               {
1032                               prior = hook;
1033                               hook = &n.next;
1034                               if ((result = dg(n.value)) != 0)
1035                                    break;
1036                               n = *hook;
1037                               }
1038                         node = n;
1039                         return result;
1040                 }                               
1041
1042                 /***************************************************************
1043
1044                         Remove value at the current iterator location
1045
1046                 ***************************************************************/
1047
1048                 bool remove ()
1049                 {
1050                         if (prior)
1051                            {
1052                            auto p = *prior;
1053                            *prior = p.next;
1054                            owner.decrement (p);
1055                            hook = prior;
1056                            prior = null;
1057
1058                            // ignore this change
1059                            ++mutation;
1060                            return true;
1061                            }
1062                         return false;
1063                 }
1064         }
1065 }
1066
1067
1068 /*******************************************************************************
1069
1070 *******************************************************************************/
1071
1072 debug (LinkedList)
1073 {
1074         import tango.io.Stdout;
1075         import tango.core.Thread;
1076         import tango.time.StopWatch;
1077
1078         void main()
1079         {
1080                 // usage examples ...
1081                 auto set = new LinkedList!(char[]);
1082                 set.add ("foo");
1083                 set.add ("bar");
1084                 set.add ("wumpus");
1085
1086                 // implicit generic iteration
1087                 foreach (value; set)
1088                          Stdout (value).newline;
1089
1090                 // explicit generic iteration   
1091                 foreach (value; set.iterator)
1092                          Stdout.formatln ("{}", value);
1093
1094                 // generic iteration with optional remove and insert
1095                 auto s = set.iterator;
1096                 foreach (value; s)
1097                 {
1098                          if (value == "foo")
1099                              s.remove;
1100                          if (value == "bar")
1101                              s.insertPrior("bloomper");
1102                          if (value == "wumpus")
1103                              s.insert("rumple");
1104                 }
1105
1106                 set.check();
1107
1108                 // incremental iteration, with optional remove
1109                 char[] v;
1110                 auto iterator = set.iterator;
1111                 while (iterator.next(v))
1112                       {} //iterator.remove;
1113                
1114                 // incremental iteration, with optional failfast
1115                 auto it = set.iterator;
1116                 while (it.valid && it.next(v))
1117                       {}
1118
1119                 // remove specific element
1120                 set.remove ("wumpus");
1121
1122                 // remove first element ...
1123                 while (set.take(v))
1124                        Stdout.formatln ("taking {}, {} left", v, set.size);
1125                
1126                
1127                 // setup for benchmark, with a set of integers. We
1128                 // use a chunk allocator, and presize the bucket[]
1129                 auto test = new LinkedList!(int, Container.reap, Container.Chunk);
1130                 test.cache (2000, 1_000_000);
1131                 const count = 1_000_000;
1132                 StopWatch w;
1133
1134                 // benchmark adding
1135                 w.start;
1136                 for (int i=count; i--;)
1137                      test.prepend(i);
1138                 Stdout.formatln ("{} adds: {}/s", test.size, test.size/w.stop);
1139
1140                 // benchmark adding without allocation overhead
1141                 test.clear;
1142                 w.start;
1143                 for (int i=count; i--;)
1144                      test.prepend(i);
1145                 Stdout.formatln ("{} adds (after clear): {}/s", test.size, test.size/w.stop);
1146
1147                 // benchmark duplication
1148                 w.start;
1149                 auto dup = test.dup;
1150                 Stdout.formatln ("{} element dup: {}/s", dup.size, dup.size/w.stop);
1151
1152                 // benchmark iteration
1153                 w.start;
1154                 auto xx = test.iterator;
1155                 int ii;
1156                 while (xx.next()) {}
1157                 Stdout.formatln ("{} element iteration: {}/s", test.size, test.size/w.stop);
1158
1159                 // benchmark iteration
1160                 w.start;
1161                 foreach (v; test) {}
1162                 Stdout.formatln ("{} foreach iteration: {}/s", test.size, test.size/w.stop);
1163
1164
1165                 // benchmark iteration
1166                 w.start;             
1167                 foreach (ref iii; test) {}
1168                 Stdout.formatln ("{} pointer iteration: {}/s", test.size, test.size/w.stop);
1169
1170                 test.check;
1171         }
1172 }
1173                
Note: See TracBrowser for help on using the browser.