00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "sort.h"
00018
00019 #include <lib/htime.h>
00020
00021 #include <stdio.h>
00022
00023
00024 char *prg_name="test-sort";
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 template<class T>struct MYOP
00038 {
00039 int ini_calls;
00040 int clr_calls;
00041 int ass_calls;
00042 int cmp_calls;
00043
00044 MYOP() { ini_calls=0; clr_calls=0; ass_calls=0; cmp_calls=0; }
00045 ~MYOP() {}
00046
00047 inline bool lt(T const &a,T const &b) const
00048 { ++((MYOP*)this)->cmp_calls; return(a<b); }
00049 inline bool le(T const &a,T const &b) const
00050 { ++((MYOP*)this)->cmp_calls; return(a<=b); }
00051 inline bool gt(T const &a,T const &b) const
00052 { ++((MYOP*)this)->cmp_calls; return(a>b); }
00053 inline bool ge(T const &a,T const &b) const
00054 { ++((MYOP*)this)->cmp_calls; return(a>=b); }
00055 inline bool eq(T const &a,T const &b) const
00056 { ++((MYOP*)this)->cmp_calls; return(a==b); }
00057 inline bool ne(T const &a,T const &b) const
00058 { ++((MYOP*)this)->cmp_calls; return(a!=b); }
00059
00060 inline T &ass(T &l,T const &r) const
00061 { ++((MYOP*)this)->ass_calls; return(l=r); }
00062
00063 static const bool pdt=1;
00064 static inline _constfn_ size_t size() { return(sizeof(T)); }
00065
00066 inline void ini(T *) const
00067 { ++((MYOP*)this)->ini_calls; }
00068 inline void ini(T *p,T const &a) const
00069 { *p=a; ++((MYOP*)this)->ini_calls; }
00070 inline void clr(T *) const
00071 { ++((MYOP*)this)->clr_calls; }
00072
00073 static inline void *alloc(size_t size) { return(ALLOC<char>(size)); }
00074 static inline void *realloc(void *ptr,size_t size)
00075 { return(REALLOC((char*)ptr,size)); }
00076 static inline void *free(void *ptr) { return(FREE(ptr)); }
00077
00078 template<typename I>static inline T &idx(T *array,I i)
00079 {
00080
00081
00082 return(array[i]);
00083 }
00084 template<typename I>static inline const T &idx(const T *array,I i)
00085 {
00086
00087 return(array[i]);
00088 }
00089 };
00090
00091
00092 int *GenRandomPerm(size_t size,size_t red)
00093 {
00094 int *array=ALLOC<int>(size);
00095 for(size_t i=0; i<size; i++)
00096 array[i]=i/red;
00097 for(size_t i=0; i<size; i++)
00098 {
00099 size_t j=rand()%size;
00100 int tmp=array[j];
00101 array[j]=array[i];
00102 array[i]=tmp;
00103 }
00104 return(array);
00105 }
00106
00107
00108 template<typename T,typename _OP>void X_DumbQuickSort(
00109 T *a,size_t nelem,
00110 const _OP &op=TLDefaultOperators_PDT<T>())
00111 { DumbQuickSort(a,nelem,13,op); }
00112
00113 template<typename T,typename _OP>void X_CleverQuickSort(
00114 T *a,size_t nelem,
00115 const _OP &op=TLDefaultOperators_PDT<T>())
00116 { CleverQuickSort(a,nelem,10,op); }
00117
00118
00119 int _DoSortAndTest(int *perm,size_t permsize,size_t red,
00120 void (*sort)(int *,size_t,const MYOP<int> &),
00121 const char *name)
00122 {
00123 int nerr=0;
00124
00125 fprintf(stderr," %s: ",name);
00126
00127 int *copy=ALLOC<int>(permsize);
00128 for(size_t i=0; i<permsize; i++) copy[i]=perm[i];
00129
00130 MYOP<int> op;
00131 HTime start(HTime::Curr);
00132 (*sort)(copy,permsize,op);
00133 long msec=start.MsecElapsed();
00134 fprintf(stderr,"ini-clr/ass/cmp=%d,%d,%d (%ld msec)",
00135 op.ini_calls-op.clr_calls,op.ass_calls,op.cmp_calls,
00136 msec);
00137
00138
00139 if(op.ini_calls!=op.clr_calls) ++nerr;
00140 for(int i=0; i<(int)permsize; i++)
00141 if(copy[i]!=(int)(i/red)) ++nerr;
00142
00143 FREE(copy);
00144
00145 if(nerr)
00146 { fprintf(stderr," ** %d errors **\n",nerr); }
00147 else
00148 { fprintf(stderr," OK\n"); }
00149
00150 return(nerr ? 1 : 0);
00151 }
00152
00153
00154 int main()
00155 {
00156 fprintf(stderr,"Testing sort algorithms...\n");
00157
00158
00159
00160
00161
00162
00163 int nerrors=0;
00164 for(size_t red=1; red<=3; red+=2)
00165 {
00166 size_t permsize=20000;
00167 int *perm=GenRandomPerm(permsize,red);
00168 fprintf(stderr," Random permutation (red=%u, size %u):\n",
00169 red,permsize);
00170
00171 nerrors+=_DoSortAndTest(perm,permsize,red,
00172 &InsertionSort< int,MYOP<int> >,
00173 "Insertion sort ");
00174 nerrors+=_DoSortAndTest(perm,permsize,red,
00175 &InsertionSortBS< int,MYOP<int> >,
00176 "Insertion sort (BS)");
00177
00178 FREE(perm);
00179
00180
00181
00182 permsize*=20;
00183 perm=GenRandomPerm(permsize,red);
00184 fprintf(stderr," Random permutation (red=%u, size %u):\n",
00185 red,permsize);
00186
00187 nerrors+=_DoSortAndTest(perm,permsize,red,
00188 &X_DumbQuickSort< int,MYOP<int> >,
00189 "Dumb Quick sort ");
00190 nerrors+=_DoSortAndTest(perm,permsize,red,
00191 &X_CleverQuickSort< int,MYOP<int> >,
00192 "Clever Quick sort ");
00193 nerrors+=_DoSortAndTest(perm,permsize,red,
00194 &HeapSort< int,MYOP<int> >,
00195 "Heap sort ");
00196
00197 FREE(perm);
00198 }
00199 if(nerrors) return(1);
00200
00201 fprintf(stderr,"TODO: Implement test for stability. **********\n");
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 LMallocUsage lmu;
00214 LMallocGetUsage(&lmu);
00215 fprintf(stderr,"%s: %sAlloc: %u bytes in %d chunks; Peak: %u by,%d chks; "
00216 "(%u/%u/%u)%s\n",
00217 prg_name,
00218 lmu.curr_used ? "*** " : "",
00219 lmu.curr_used,lmu.used_chunks,lmu.max_used,lmu.max_used_chunks,
00220 lmu.malloc_calls,lmu.realloc_calls,lmu.free_calls,
00221 lmu.curr_used ? " ***" : "");
00222 if(lmu.curr_used) return(1);
00223
00224 fprintf(stderr,"Sort test SUCCESSFUL.\n");
00225 return(0);
00226 }