#include <chrono>
#include <ctime>
#include <type_traits>
#include <tuple>
#include <iostream>
#include <algorithm>
#include <functional>
#include "smoothsort.h"
#include "timsort.h"
// http://b...content-available-to-author-only...r.ca/2012/05/13/timing-functions-with-chrono.html
template <typename Clock, typename Func>
inline typename Clock::duration time_function(Func&& f)
{
auto start_time = Clock::now();
f();
auto time_taken = Clock::now() - start_time;
return time_taken;
}
enum state_t
{
sorted, randomized, reversed, partially_sorted_0, partially_sorted_1
};
template <typename value_t>
static void bench(int const size, state_t const state)
{
typedef std::chrono::high_resolution_clock clock_type;
std::cerr << "size\t" << size << std::endl;
std::less<value_t> lt;
std::greater<value_t> gt;
std::vector<value_t> a;
for(int i = 0; i < size; ++i)
{
a.push_back((i+1) * 10);
}
switch(state)
{
case randomized:
std::random_shuffle(a.begin(), a.end());
break;
case reversed:
std::reverse(a.begin(), a.end());
break;
case sorted:
break;
case partially_sorted_0:
{
std::random_shuffle(a.begin(), a.end());
bool toggle = true;
for(auto i=a.begin(); i < a.end(); i+=10)
{
if(toggle)
std::stable_sort(i, i+10, lt);
else
std::stable_sort(i, i+10, gt);
toggle = !toggle;
}
}
break;
case partially_sorted_1:
{
std::random_shuffle(a.begin(), a.end());
bool toggle = true;
for(auto i=a.begin(); i < a.end(); i+=1000)
{
if(toggle)
std::stable_sort(i, i+1000, lt);
else
std::stable_sort(i, i+1000, gt);
toggle = !toggle;
}
}
break;
default:
assert(!"not reached");
}
{
std::vector<value_t> b(a);
auto duration = time_function<clock_type>([&]
{
for(int i = 0; i < 100; ++i)
{
std::copy(a.begin(), a.end(), b.begin());
std::sort(b.begin(), b.end(), lt);
}
});
std::cerr << "std::sort " << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << " ms" << std::endl;
}
{
std::vector<value_t> b(a);
auto duration = time_function<clock_type>([&]
{
for(int i = 0; i < 100; ++i)
{
std::copy(a.begin(), a.end(), b.begin());
std::stable_sort(b.begin(), b.end(), lt);
}
});
std::cerr << "std::stable_sort " << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << " ms" << std::endl;
}
{
std::vector<value_t> b(a);
auto duration = time_function<clock_type>([&]
{
for(int i = 0; i < 100; ++i)
{
std::copy(a.begin(), a.end(), b.begin());
Smoothsort(b.begin(), b.end(), lt);
}
});
std::cerr << "smoothsort " << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << " ms" << std::endl;
}
{
std::vector<value_t> b(a);
auto duration = time_function<clock_type>([&]
{
for(int i = 0; i < 100; ++i)
{
std::copy(a.begin(), a.end(), b.begin());
timsort(b.begin(), b.end(), lt);
}
});
std::cerr << "timsort " << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << " ms" << std::endl;
}
}
static void doit(int const n, state_t const state) {
std::cerr << "int" << std::endl;
bench<int>(n, state);
std::cerr << "double" << std::endl;
bench<double>(n, state);
}
int main(int argc, char* argv[])
{
const int N = 1000*100;
std::srand(static_cast<unsigned int>(std::time(NULL)));
std::cout << "RANDOMIZED SEQUENCE" << std::endl;
doit(N, randomized);
std::cout << std::endl;
std::cout << "REVERSED SEQUENCE" << std::endl;
doit(N, reversed);
std::cout << std::endl;
std::cout << "SORTED SEQUENCE" << std::endl;
doit(N, sorted);
std::cout << std::endl;
std::cout << "PARTIALLY SORTED SEQUENCE 0" << std::endl;
doit(N, partially_sorted_0);
std::cout << std::endl;
std::cout << "PARTIALLY SORTED SEQUENCE 1" << std::endl;
doit(N, partially_sorted_1);
std::cout << std::endl;
return 0;
}