#include using namespace Upp; template void FwSort2(I begin, I end, const Less& less) { while(begin != end && begin + 1 != end) { I min = begin; I max = begin; for(I i = begin + 1; i != end; i++) { if(less(*i, *min)) min = i; if(!less(*i, *max)) max = i; } IterSwap(begin, min); IterSwap(--end, max == begin ? min : max); begin++; } } template void FwSortSimple(I begin, I end, const Less& less) { while(begin != end) { I min = begin; for(I i = begin; ++i != end;) if(less(*i, *min)) min = i; IterSwap(begin++, min); } } template inline int SelectMin2(I ptr, int i, const Less& less) { return less(ptr[i + 1], ptr[i]); } template inline int SelectMin3(I ptr, int i, const Less& less) { int l = SelectMin2(ptr, less); I h = ptr + 2; return less(*l, *h) ? l : h; } template inline I SelectMin4(I ptr, const Less& less) { I l = SelectMin2(ptr, less); I h = SelectMin2(ptr + 2, less); return less(*l, *h) ? l : h; } template inline I SelectMin5(I ptr, const Less& less) { I l = SelectMin4(ptr, less); I h = ptr + 4; return less(*l, *h) ? l : h; } template inline I SelectMin6(I ptr, const Less& less) { I l = SelectMin4(ptr, less); I h = SelectMin2(ptr + 4, less); return less(*l, *h) ? l : h; } template inline I SelectMin7(I ptr, const Less& less) { I l = SelectMin4(ptr, less); I h = SelectMin3(ptr + 4, less); return less(*l, *h) ? l : h; } template inline I SelectMin8(I ptr, const Less& less) { I l = SelectMin4(ptr, less); I h = SelectMin4(ptr + 4, less); return less(*l, *h) ? l : h; } template inline I SelectMin9(I ptr, const Less& less) { I l = SelectMin8(ptr, less); I h = ptr + 8; return less(*l, *h) ? l : h; } template inline I SelectMin10(I ptr, const Less& less) { I l = SelectMin8(ptr, less); I h = SelectMin2(ptr + 8, less); return less(*l, *h) ? l : h; } template inline I SelectMin11(I ptr, const Less& less) { I l = SelectMin8(ptr, less); I h = SelectMin3(ptr + 8, less); return less(*l, *h) ? l : h; } template inline I SelectMin12(I ptr, const Less& less) { I l = SelectMin8(ptr, less); I h = SelectMin4(ptr + 8, less); return less(*l, *h) ? l : h; } template inline I SelectMin13(I ptr, const Less& less) { I l = SelectMin8(ptr, less); I h = SelectMin5(ptr + 8, less); return less(*l, *h) ? l : h; } template inline I SelectMin14(I ptr, const Less& less) { I l = SelectMin8(ptr, less); I h = SelectMin6(ptr + 8, less); return less(*l, *h) ? l : h; } template inline I SelectMin15(I ptr, const Less& less) { I l = SelectMin8(ptr, less); I h = SelectMin7(ptr + 8, less); return less(*l, *h) ? l : h; } template inline I SelectMin16(I ptr, const Less& less) { I l = SelectMin8(ptr, less); I h = SelectMin8(ptr + 8, less); return less(*l, *h) ? l : h; } template void FwSort(I begin, int len, const Less& less) { switch(len) { case 16: IterSwap(begin, SelectMin16(begin, less)); begin++; case 15: IterSwap(begin, SelectMin15(begin, less)); begin++; case 14: IterSwap(begin, SelectMin14(begin, less)); begin++; case 13: IterSwap(begin, SelectMin13(begin, less)); begin++; case 12: IterSwap(begin, SelectMin12(begin, less)); begin++; case 11: IterSwap(begin, SelectMin11(begin, less)); begin++; case 10: IterSwap(begin, SelectMin10(begin, less)); begin++; case 9: IterSwap(begin, SelectMin9(begin, less)); begin++; case 8: IterSwap(begin, SelectMin8(begin, less)); begin++; case 7: IterSwap(begin, SelectMin7(begin, less)); begin++; case 6: IterSwap(begin, SelectMin6(begin, less)); begin++; case 5: IterSwap(begin, SelectMin5(begin, less)); begin++; case 4: IterSwap(begin, SelectMin4(begin, less)); begin++; case 3: IterSwap(begin, SelectMin3(begin, less)); begin++; case 2: IterSwap(begin, SelectMin2(begin, less)); } } template void Dump(const Vector& data) { String s; for(int q = 0; q < data.GetCount(); q++) s << data[q] << ' '; LOG(s); } CONSOLE_APP_MAIN { #ifdef _DEBUG Vector x; x << 40 << 20 << 4 << 10 << 11 << 17 << 2 << 12; FwSort(x.Begin(), x.GetCount(), StdLess()); Dump(x); Vector y; y << "40" << "20" << "4" << "10" << "11" << "17" << "2" << "12"; FwSort(y.Begin(), y.GetCount(), StdLess()); Dump(y); for(int i = 0; i < 10; i++) { Vector data; int n = rand() % 16; for(int q = 0; q < n; q++) data.Add(rand() % 100); Dump(data); FwSort(data.Begin(), data.GetCount(), StdLess()); Dump(data); LOG("----"); } #else Vector< Vector > set; for(int i = 0; i < 1000; i++) { Vector& data = set.Add(); int n = rand() % 15; n = 8; for(int q = 0; q < n; q++) data.Add(rand() % 100); } double x = 100.0 * set.GetCount(); RDUMP(x); dword time = GetTickCount(); while(time + 3000 > GetTickCount()) { Vector< Vector > s; s <<= set; { RTIMING("Simple FW sort"); for(int i = 0; i < s.GetCount(); i++) ForwardSort(s[i].Begin(), s[i].End(), StdLess()); } s <<= set; { RTIMING("Normal FW sort"); for(int i = 0; i < s.GetCount(); i++) ForwardSort(s[i].Begin(), s[i].End(), StdLess()); } s <<= set; { RTIMING("New FW sort"); for(int i = 0; i < s.GetCount(); i++) FwSort(s[i].Begin(), s[i].GetCount(), StdLess()); } } #endif }