আমি সম্প্রতি একটি সামান্য ক্লাস লিখেছি যা সংকলনের সময় বাছাইয়ের নেটওয়ার্ক তৈরি করতে বোস-নেলসন অ্যালগরিদম ব্যবহার করে।
এটি 10 সংখ্যার জন্য খুব দ্রুত বাছাই করতে ব্যবহৃত হতে পারে।
/**
* A Functor class to create a sort for fixed sized arrays/containers with a
* compile time generated Bose-Nelson sorting network.
* \tparam NumElements The number of elements in the array or container to sort.
* \tparam T The element type.
* \tparam Compare A comparator functor class that returns true if lhs < rhs.
*/
template <unsigned NumElements, class Compare = void> class StaticSort
{
template <class A, class C> struct Swap
{
template <class T> inline void s(T &v0, T &v1)
{
T t = Compare()(v0, v1) ? v0 : v1; // Min
v1 = Compare()(v0, v1) ? v1 : v0; // Max
v0 = t;
}
inline Swap(A &a, const int &i0, const int &i1) { s(a[i0], a[i1]); }
};
template <class A> struct Swap <A, void>
{
template <class T> inline void s(T &v0, T &v1)
{
// Explicitly code out the Min and Max to nudge the compiler
// to generate branchless code.
T t = v0 < v1 ? v0 : v1; // Min
v1 = v0 < v1 ? v1 : v0; // Max
v0 = t;
}
inline Swap(A &a, const int &i0, const int &i1) { s(a[i0], a[i1]); }
};
template <class A, class C, int I, int J, int X, int Y> struct PB
{
inline PB(A &a)
{
enum { L = X >> 1, M = (X & 1 ? Y : Y + 1) >> 1, IAddL = I + L, XSubL = X - L };
PB<A, C, I, J, L, M> p0(a);
PB<A, C, IAddL, J + M, XSubL, Y - M> p1(a);
PB<A, C, IAddL, J, XSubL, M> p2(a);
}
};
template <class A, class C, int I, int J> struct PB <A, C, I, J, 1, 1>
{
inline PB(A &a) { Swap<A, C> s(a, I - 1, J - 1); }
};
template <class A, class C, int I, int J> struct PB <A, C, I, J, 1, 2>
{
inline PB(A &a) { Swap<A, C> s0(a, I - 1, J); Swap<A, C> s1(a, I - 1, J - 1); }
};
template <class A, class C, int I, int J> struct PB <A, C, I, J, 2, 1>
{
inline PB(A &a) { Swap<A, C> s0(a, I - 1, J - 1); Swap<A, C> s1(a, I, J - 1); }
};
template <class A, class C, int I, int M, bool Stop = false> struct PS
{
inline PS(A &a)
{
enum { L = M >> 1, IAddL = I + L, MSubL = M - L};
PS<A, C, I, L, (L <= 1)> ps0(a);
PS<A, C, IAddL, MSubL, (MSubL <= 1)> ps1(a);
PB<A, C, I, IAddL, L, MSubL> pb(a);
}
};
template <class A, class C, int I, int M> struct PS <A, C, I, M, true>
{
inline PS(A &a) {}
};
public:
/**
* Sorts the array/container arr.
* \param arr The array/container to be sorted.
*/
template <class Container> inline void operator() (Container &arr) const
{
PS<Container, Compare, 1, NumElements, (NumElements <= 1)> ps(arr);
};
/**
* Sorts the array arr.
* \param arr The array to be sorted.
*/
template <class T> inline void operator() (T *arr) const
{
PS<T*, Compare, 1, NumElements, (NumElements <= 1)> ps(arr);
};
};
#include <iostream>
#include <vector>
int main(int argc, const char * argv[])
{
enum { NumValues = 10 };
// Arrays
{
int rands[NumValues];
for (int i = 0; i < NumValues; ++i) rands[i] = rand() % 100;
std::cout << "Before Sort: \t";
for (int i = 0; i < NumValues; ++i) std::cout << rands[i] << " ";
std::cout << "\n";
StaticSort<NumValues> staticSort;
staticSort(rands);
std::cout << "After Sort: \t";
for (int i = 0; i < NumValues; ++i) std::cout << rands[i] << " ";
std::cout << "\n";
}
std::cout << "\n";
// STL Vector
{
std::vector<int> rands(NumValues);
for (int i = 0; i < NumValues; ++i) rands[i] = rand() % 100;
std::cout << "Before Sort: \t";
for (int i = 0; i < NumValues; ++i) std::cout << rands[i] << " ";
std::cout << "\n";
StaticSort<NumValues> staticSort;
staticSort(rands);
std::cout << "After Sort: \t";
for (int i = 0; i < NumValues; ++i) std::cout << rands[i] << " ";
std::cout << "\n";
}
return 0;
}
মনে রাখবেন যে একটি if (compare) swap
বিবৃতি পরিবর্তে , আমরা স্পষ্টভাবে ন্যূনতম এবং সর্বাধিক জন্য টার্নারি অপারেটরদের কোড আউট করি। এটি শাখাবিহীন কোড ব্যবহার করে সংকলককে টোকা দিতে সহায়তা করে।
benchmarks
নিম্নলিখিত মানদণ্ডগুলি ঝনঝন -৩৩ এর সাথে সংকলিত হয়ে আমার ২০১২ সালের মাঝামাঝি ম্যাকবুক এয়ারে চলেছে।
এলোমেলো তথ্য বাছাই করা হচ্ছে
দারিওপির কোডের সাথে এটির তুলনা করে, 10 মাপের 1 মিলিয়ন 32-বিট ইন্টি অ্যারেগুলি সাজানোর জন্য এখানে মিলি সেকেন্ডের সংখ্যা রয়েছে:
হার্ডকোডযুক্ত বাছাই নেট 10: 88.774 এমএস
বোস-নেলসন সাজান 10: 27.815 এমএস
এই টেম্পলেটেড পদ্ধতির ব্যবহার করে, আমরা অন্যান্য সংখ্যক উপাদানের সংকলনের সময় বাছাই করা নেটওয়ার্কগুলিও তৈরি করতে পারি।
বিভিন্ন আকারের 1 মিলিয়ন অ্যারে বাছাই করতে সময় (মিলিসেকেন্ডে)।
আকার 2, 4, 8 এর অ্যারেগুলির জন্য মিলিসেকেন্ডগুলির সংখ্যা যথাক্রমে 1.943, 8.655, 20.246।
ক্রেডিট নিবন্ধিত সন্নিবেশ সাজানোর জন্য গ্লেন টিটেলবাউমে ।
এখানে 6 টি উপাদানের ছোট অ্যারেগুলির জন্য সাজানোর জন্য গড় ঘড়ি রয়েছে। এই প্রশ্নটিতে বেঞ্চমার্ক কোড এবং উদাহরণগুলি পাওয়া যাবে:
নির্দিষ্টতম দৈর্ঘ্যের 6 ইনট অ্যারের দ্রুততম ধরণের
Direct call to qsort library function : 326.81
Naive implementation (insertion sort) : 132.98
Insertion Sort (Daniel Stutzbach) : 104.04
Insertion Sort Unrolled : 99.64
Insertion Sort Unrolled (Glenn Teitelbaum) : 81.55
Rank Order : 44.01
Rank Order with registers : 42.40
Sorting Networks (Daniel Stutzbach) : 88.06
Sorting Networks (Paul R) : 31.64
Sorting Networks 12 with Fast Swap : 29.68
Sorting Networks 12 reordered Swap : 28.61
Reordered Sorting Network w/ fast swap : 24.63
Templated Sorting Network (this class) : 25.37
এটি 6 টি উপাদানের জন্য প্রশ্নের দ্রুততম উদাহরণ হিসাবে তত দ্রুত সম্পাদন করে।
বাছাই করা ডেটা বাছাইয়ের জন্য পারফরম্যান্স
প্রায়শই, ইনপুট অ্যারেগুলি ইতিমধ্যে বাছাই করা বা বেশিরভাগ বাছাই করা যেতে পারে।
এই ধরনের ক্ষেত্রে, সন্নিবেশ সাজানোর আরও ভাল পছন্দ হতে পারে।
আপনি ডেটা উপর নির্ভর করে একটি উপযুক্ত বাছাই অ্যালগরিদম চয়ন করতে চাইতে পারেন।
মানদণ্ডগুলির জন্য ব্যবহৃত কোডটি এখানে পাওয়া যাবে ।
if
বিবৃতিগুলির একটি সিরিজ সেরা কাজ করা উচিত। লুপগুলি এড়িয়ে চলুন।