mirror of
https://github.com/boostorg/sort.git
synced 2026-01-19 04:42:11 +00:00
317 lines
9.9 KiB
C++
317 lines
9.9 KiB
C++
//----------------------------------------------------------------------------
|
|
/// @file benchmark_strings.cpp
|
|
/// @brief Benchmark of several sort methods with strings
|
|
///
|
|
/// @author Copyright (c) 2017 Francisco José Tapia (fjtapia@gmail.com )\n
|
|
/// Distributed under the Boost Software License, Version 1.0.\n
|
|
/// ( See accompanying file LICENSE_1_0.txt or copy at
|
|
/// http://www.boost.org/LICENSE_1_0.txt )
|
|
///
|
|
/// This program use for comparison purposes, the Threading Building
|
|
/// Blocks which license is the GNU General Public License, version 2
|
|
/// as published by the Free Software Foundation.
|
|
///
|
|
/// @version 0.1
|
|
///
|
|
/// @remarks
|
|
//-----------------------------------------------------------------------------
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <random>
|
|
#include <stdlib.h>
|
|
#include <vector>
|
|
|
|
#include <boost/sort/common/time_measure.hpp>
|
|
#include <boost/sort/common/file_vector.hpp>
|
|
#include <boost/sort/common/int_array.hpp>
|
|
|
|
#include <boost/sort/sort.hpp>
|
|
|
|
|
|
#define NMAXSTRING 10000000
|
|
|
|
using namespace std;
|
|
namespace bsc = boost::sort::common;
|
|
namespace bsp = boost::sort;
|
|
using bsc::time_point;
|
|
using bsc::now;
|
|
using bsc::subtract_time;
|
|
|
|
|
|
void Generator_random (void);
|
|
void Generator_sorted (void);
|
|
void Generator_sorted_end( size_t n_last);
|
|
void Generator_sorted_middle (size_t n_middle);
|
|
void Generator_reverse_sorted (void);
|
|
void Generator_reverse_sorted_end (size_t n_last);
|
|
void Generator_reverse_sorted_middle (size_t n_middle);
|
|
|
|
void Test (std::vector <std::string> &B);
|
|
|
|
|
|
int main(int argc, char *argv [])
|
|
{
|
|
cout << "\n\n";
|
|
cout << "************************************************************\n";
|
|
cout << "** **\n";
|
|
cout << "** B O O S T S O R T P A R A L L E L **\n";
|
|
cout << "** S T R I N G S B E N C H M A R K **\n";
|
|
cout << "** **\n";
|
|
cout << "** S O R T O F 10 000 000 S T R I N G S **\n";
|
|
cout << "** **\n";
|
|
cout << "************************************************************\n";
|
|
cout << std::endl;
|
|
|
|
cout << "[ 1 ] block_indirect_sort [ 2 ] sample_sort\n";
|
|
cout << "[ 3 ] parallel_stable_sort\n\n";
|
|
cout << " | | | |\n";
|
|
cout << " | [ 1 ]| [ 2 ]| [ 3 ]|\n";
|
|
cout << "--------------------+------+------+------+\n";
|
|
std::string empty_line =
|
|
" | | | |\n";
|
|
|
|
cout << "random |";
|
|
Generator_random ();
|
|
|
|
cout << empty_line;
|
|
cout << "sorted |";
|
|
Generator_sorted ();
|
|
|
|
cout << "sorted + 0.1% end |";
|
|
Generator_sorted_end (NMAXSTRING / 1000);
|
|
|
|
cout << "sorted + 1% end |";
|
|
Generator_sorted_end (NMAXSTRING / 100);
|
|
|
|
cout << "sorted + 10% end |";
|
|
Generator_sorted_end (NMAXSTRING / 10);
|
|
|
|
cout << empty_line;
|
|
cout << "sorted + 0.1% mid |";
|
|
Generator_sorted_middle (NMAXSTRING / 1000);
|
|
|
|
cout << "sorted + 1% mid |";
|
|
Generator_sorted_middle (NMAXSTRING / 100);
|
|
|
|
cout << "sorted + 10% mid |";
|
|
Generator_sorted_middle (NMAXSTRING / 10 );
|
|
|
|
cout << empty_line;
|
|
cout << "reverse sorted |";
|
|
Generator_reverse_sorted ();
|
|
|
|
cout << "rv sorted + 0.1% end|";
|
|
Generator_reverse_sorted_end (NMAXSTRING / 1000);
|
|
|
|
cout << "rv sorted + 1% end|";
|
|
Generator_reverse_sorted_end (NMAXSTRING / 100);
|
|
|
|
cout << "rv sorted + 10% end|";
|
|
Generator_reverse_sorted_end (NMAXSTRING / 10);
|
|
|
|
cout << empty_line;
|
|
cout << "rv sorted + 0.1% mid|";
|
|
Generator_reverse_sorted_middle (NMAXSTRING / 1000);
|
|
|
|
cout << "rv sorted + 1% mid|";
|
|
Generator_reverse_sorted_middle (NMAXSTRING / 100);
|
|
|
|
cout << "rv sorted + 10% mid|";
|
|
Generator_reverse_sorted_middle (NMAXSTRING / 10);
|
|
|
|
cout << "--------------------+------+------+------+\n";
|
|
cout << endl <<endl ;
|
|
return 0;
|
|
}
|
|
|
|
void Generator_random (void)
|
|
{
|
|
std::vector <std::string> A;
|
|
A.reserve (NMAXSTRING);
|
|
A.clear ();
|
|
if (bsc::fill_vector_string ("input.bin", A, NMAXSTRING) != 0)
|
|
{
|
|
std::cout << "Error in the input file\n";
|
|
std::exit (EXIT_FAILURE);
|
|
};
|
|
Test (A);
|
|
};
|
|
void Generator_sorted (void)
|
|
{
|
|
std::vector <std::string> A;
|
|
A.reserve (NMAXSTRING);
|
|
A.clear ();
|
|
if (bsc::fill_vector_string ("input.bin", A, NMAXSTRING) != 0)
|
|
{
|
|
std::cout << "Error in the input file\n";
|
|
std::exit (EXIT_FAILURE);
|
|
};
|
|
std::sort (A.begin (), A.end ());
|
|
Test (A);
|
|
};
|
|
|
|
void Generator_sorted_end (size_t n_last)
|
|
{
|
|
std::vector <std::string> A;
|
|
A.reserve (NMAXSTRING);
|
|
A.clear ();
|
|
if (bsc::fill_vector_string ("input.bin", A, NMAXSTRING+ n_last) != 0)
|
|
{
|
|
std::cout << "Error in the input file\n";
|
|
std::exit (EXIT_FAILURE);
|
|
};
|
|
std::sort (A.begin (), A.begin () + NMAXSTRING );
|
|
Test (A);
|
|
};
|
|
void Generator_sorted_middle (size_t n_middle)
|
|
{
|
|
assert (n_middle > 1 && NMAXSTRING >= (n_middle -1));
|
|
vector <std::string> A, aux;
|
|
A.reserve (NMAXSTRING + n_middle);
|
|
aux.reserve (n_middle);
|
|
|
|
if (bsc::fill_vector_string ("input.bin", A, NMAXSTRING + n_middle) != 0)
|
|
{
|
|
std::cout << "Error in the input file\n";
|
|
std::exit (EXIT_FAILURE);
|
|
};
|
|
for (size_t i = 0; i < n_middle; ++i) aux.push_back (std::move (A [i]));
|
|
|
|
std::sort (A.begin () + n_middle, A.end ());
|
|
//------------------------------------------------------------------------
|
|
// To insert n_middle elements, must have (n_middle - 1) intervals between
|
|
// them. The size of the interval is step
|
|
// The elements after the last element of aux don't need to be moved
|
|
//-------------------------------------------------------------------------
|
|
size_t step = NMAXSTRING / (n_middle - 1);
|
|
A [0] = std::move (aux [0]);
|
|
size_t pos_read = n_middle, pos_write = 1;
|
|
|
|
for (size_t i = 1; i < n_middle; ++i)
|
|
{
|
|
for (size_t k = 0 ; k < step; ++k)
|
|
A [pos_write ++] = std::move (A [pos_read ++]);
|
|
A [pos_write ++] = std::move (aux [i]);
|
|
};
|
|
aux.clear ();
|
|
aux.reserve (0);
|
|
Test (A);
|
|
};
|
|
void Generator_reverse_sorted (void)
|
|
{
|
|
std::vector <std::string> A;
|
|
A.reserve (NMAXSTRING);
|
|
{
|
|
std::vector <std::string> B;
|
|
B.reserve (NMAXSTRING);
|
|
if (bsc::fill_vector_string ("input.bin", B, NMAXSTRING) != 0)
|
|
{
|
|
std::cout << "Error in the input file\n";
|
|
std::exit (EXIT_FAILURE);
|
|
};
|
|
std::sort (B.begin(), B.end());
|
|
A.clear ();
|
|
for (size_t i = 0; i < NMAXSTRING; ++i)
|
|
A.push_back (B [NMAXSTRING - 1 - i]);
|
|
};
|
|
Test (A);
|
|
};
|
|
void Generator_reverse_sorted_end (size_t n_last)
|
|
{
|
|
std::vector <std::string> A;
|
|
A.reserve (NMAXSTRING);
|
|
A.clear ();
|
|
if (bsc::fill_vector_string ("input.bin", A, NMAXSTRING + n_last) != 0)
|
|
{
|
|
std::cout << "Error in the input file\n";
|
|
std::exit (EXIT_FAILURE);
|
|
};
|
|
std::sort (A.begin (), A.begin () + NMAXSTRING);
|
|
for (size_t i = 0; i < (NMAXSTRING >> 1); ++i)
|
|
std::swap (A [i], A [NMAXSTRING - 1 - i]);
|
|
|
|
Test (A);
|
|
};
|
|
void Generator_reverse_sorted_middle (size_t n_middle)
|
|
{
|
|
assert (n_middle > 1 && NMAXSTRING >= (n_middle -1));
|
|
vector <std::string> A, aux;
|
|
A.reserve (NMAXSTRING + n_middle);
|
|
aux.reserve (n_middle);
|
|
|
|
if (bsc::fill_vector_string ("input.bin", A, NMAXSTRING + n_middle) != 0)
|
|
{
|
|
std::cout << "Error in the input file\n";
|
|
std::exit (EXIT_FAILURE);
|
|
};
|
|
for (size_t i = 0; i < n_middle; ++i) aux.push_back (std::move (A [i]));
|
|
|
|
std::sort (A.begin () + n_middle, A.end ());
|
|
|
|
size_t pos1 = n_middle, pos2 = A.size () - 1;
|
|
for (size_t i = 0; i < (NMAXSTRING >> 1); ++i)
|
|
std::swap (A [pos1 ++], A [pos2 --]);
|
|
|
|
//------------------------------------------------------------------------
|
|
// To insert n_middle elements, must have (n_middle - 1) intervals between
|
|
// them. The size of the interval is step
|
|
// The elements after the last element of aux don't need to be moved
|
|
//-------------------------------------------------------------------------
|
|
size_t step = NMAXSTRING / (n_middle - 1);
|
|
A [0] = std::move (aux [0]);
|
|
size_t pos_read = n_middle, pos_write = 1;
|
|
|
|
for (size_t i = 1; i < n_middle; ++i)
|
|
{
|
|
for (size_t k = 0 ; k < step; ++k)
|
|
A [pos_write ++] = std::move (A [pos_read ++]);
|
|
A [pos_write ++] = std::move (aux [i]);
|
|
};
|
|
aux.clear ();
|
|
aux.reserve (0);
|
|
Test (A);
|
|
};
|
|
|
|
void Test (std::vector <std::string> &B)
|
|
{ //---------------------------- begin --------------------------------
|
|
std::less <std::string> comp;
|
|
double duration;
|
|
time_point start, finish;
|
|
std::vector <std::string> A (B);
|
|
std::vector <double> V;
|
|
|
|
//--------------------------------------------------------------------
|
|
A = B;
|
|
start = now ();
|
|
bsp::block_indirect_sort (A.begin (), A.end (), comp);
|
|
finish = now ();
|
|
duration = subtract_time (finish, start);
|
|
V.push_back (duration);
|
|
|
|
A = B;
|
|
start = now ();
|
|
bsp::sample_sort (A.begin (), A.end (), comp);
|
|
finish = now ();
|
|
duration = subtract_time (finish, start);
|
|
V.push_back (duration);
|
|
|
|
A = B;
|
|
start = now ();
|
|
bsp::parallel_stable_sort (A.begin (), A.end (), comp);
|
|
finish = now ();
|
|
duration = subtract_time (finish, start);
|
|
V.push_back (duration);
|
|
|
|
//-----------------------------------------------------------------------
|
|
// printing the vector
|
|
//-----------------------------------------------------------------------
|
|
std::cout << std::setprecision (2) << std::fixed;
|
|
for (uint32_t i = 0; i < V.size (); ++i)
|
|
{ std::cout << std::right << std::setw (5) << V [i] << " |";
|
|
};
|
|
std::cout << std::endl;
|
|
|
|
};
|
|
|