From: Chris Jefferson Date: Mon, 30 Sep 2013 17:43:05 +0000 (+0000) Subject: re PR libstdc++/58437 (Sorting value in reverse order is much slower compare to gcc44) X-Git-Tag: releases/gcc-4.7.4~467 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7d43611b8096af5ecc8c329117590ef09805c7ce;p=thirdparty%2Fgcc.git re PR libstdc++/58437 (Sorting value in reverse order is much slower compare to gcc44) 2013-09-30 Chris Jefferson PR libstdc++/58437 * include/bits/stl_algo.h (__move_median_first): Rename to __move_median_to_first, change to take an addition argument. (__unguarded_partition_pivot): Adjust. * testsuite/performance/25_algorithms/sort.cc: New. * testsuite/performance/25_algorithms/sort_heap.cc: Likewise. * testsuite/performance/25_algorithms/stable_sort.cc: Likewise. From-SVN: r203037 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 19707c2c7839..d5aebe8c9072 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2013-09-30 Chris Jefferson + + PR libstdc++/58437 + * include/bits/stl_algo.h (__move_median_first): Rename to + __move_median_to_first, change to take an addition argument. + (__unguarded_partition_pivot): Adjust. + * testsuite/performance/25_algorithms/sort.cc: New. + * testsuite/performance/25_algorithms/sort_heap.cc: Likewise. + * testsuite/performance/25_algorithms/stable_sort.cc: Likewise. + 2013-09-26 Jonathan Wakely Backport from mainline diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index f337e0c07a65..239b63c233fe 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -74,10 +74,11 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - /// Swaps the median value of *__a, *__b and *__c to *__a + /// Swaps the median value of *__a, *__b and *__c to *__result template void - __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c) + __move_median_to_first(_Iterator __result, _Iterator __a, + _Iterator __b, _Iterator __c) { // concept requirements __glibcxx_function_requires(_LessThanComparableConcept< @@ -86,23 +87,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (*__a < *__b) { if (*__b < *__c) - std::iter_swap(__a, __b); + std::iter_swap(__result, __b); else if (*__a < *__c) - std::iter_swap(__a, __c); + std::iter_swap(__result, __c); + else + std::iter_swap(__result, __a); } else if (*__a < *__c) - return; + std::iter_swap(__result, __a); else if (*__b < *__c) - std::iter_swap(__a, __c); + std::iter_swap(__result, __c); else - std::iter_swap(__a, __b); + std::iter_swap(__result, __b); } - /// Swaps the median value of *__a, *__b and *__c under __comp to *__a + /// Swaps the median value of *__a, *__b and *__c under __comp to *__result template void - __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c, - _Compare __comp) + __move_median_to_first(_Iterator __result, _Iterator __a, + _Iterator __b, _Iterator __c, + _Compare __comp) { // concept requirements __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool, @@ -112,16 +116,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__comp(*__a, *__b)) { if (__comp(*__b, *__c)) - std::iter_swap(__a, __b); + std::iter_swap(__result, __b); else if (__comp(*__a, *__c)) - std::iter_swap(__a, __c); + std::iter_swap(__result, __c); + else + std::iter_swap(__result, __a); } else if (__comp(*__a, *__c)) - return; + std::iter_swap(__result, __a); else if (__comp(*__b, *__c)) - std::iter_swap(__a, __c); + std::iter_swap(__result, __c); else - std::iter_swap(__a, __b); + std::iter_swap(__result, __b); } // for_each @@ -2305,7 +2311,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _RandomAccessIterator __last) { _RandomAccessIterator __mid = __first + (__last - __first) / 2; - std::__move_median_first(__first, __mid, (__last - 1)); + std::__move_median_to_first(__first, __first + 1, __mid, (__last - 2)); return std::__unguarded_partition(__first + 1, __last, *__first); } @@ -2317,7 +2323,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _RandomAccessIterator __last, _Compare __comp) { _RandomAccessIterator __mid = __first + (__last - __first) / 2; - std::__move_median_first(__first, __mid, (__last - 1), __comp); + std::__move_median_to_first(__first, __first + 1, __mid, (__last - 2), + __comp); return std::__unguarded_partition(__first + 1, __last, *__first, __comp); } diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/sort.cc b/libstdc++-v3/testsuite/performance/25_algorithms/sort.cc new file mode 100644 index 000000000000..07062ab8b3f4 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/25_algorithms/sort.cc @@ -0,0 +1,65 @@ +// Copyright (C) 2013 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include +#include + +int main() +{ + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + + const int max_size = 10000000; + + std::vector v(max_size); + + for (int i = 0; i < max_size; ++i) + v[i] = -i; + + start_counters(time, resource); + std::sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "reverse", time, resource); + clear_counters(time, resource); + + for (int i = 0; i < max_size; ++i) + v[i] = i; + + start_counters(time, resource); + std::sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "forwards", time, resource); + clear_counters(time, resource); + + // a simple psuedo-random series which does not rely on rand() and friends + v[0] = 0; + for (int i = 1; i < max_size; ++i) + v[i] = (v[i-1] + 110211473) * 745988807; + + start_counters(time, resource); + std::sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "random", time, resource); + + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/sort_heap.cc b/libstdc++-v3/testsuite/performance/25_algorithms/sort_heap.cc new file mode 100644 index 000000000000..63cb22480336 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/25_algorithms/sort_heap.cc @@ -0,0 +1,73 @@ +// Copyright (C) 2013 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include +#include + +int main() +{ + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + + const int max_size = 10000000; + + std::vector v(max_size); + + for (int i = 0; i < max_size; ++i) + v[i] = -i; + + start_counters(time, resource); + std::make_heap(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "make_heap_reverse", time, resource); + clear_counters(time, resource); + + for (int i = 0; i < max_size; ++i) + v[i] = i; + + start_counters(time, resource); + std::make_heap(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "make_heap_forwards", time, resource); + clear_counters(time, resource); + + // a simple psuedo-random series which does not rely on rand() and friends + v[0] = 0; + for (int i = 1; i < max_size; ++i) + v[i] = (v[i-1] + 110211473) * 745988807; + + start_counters(time, resource); + std::make_heap(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "make_heap_random", time, resource); + + + start_counters(time, resource); + std::sort_heap(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "sort_heap", time, resource); + clear_counters(time, resource); + + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc b/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc new file mode 100644 index 000000000000..6440eb35f8f5 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc @@ -0,0 +1,65 @@ +// Copyright (C) 2013 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include +#include + +int main() +{ + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + + const int max_size = 10000000; + + std::vector v(max_size); + + for (int i = 0; i < max_size; ++i) + v[i] = -i; + + start_counters(time, resource); + std::stable_sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "reverse", time, resource); + clear_counters(time, resource); + + for (int i = 0; i < max_size; ++i) + v[i] = i; + + start_counters(time, resource); + std::stable_sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "forwards", time, resource); + clear_counters(time, resource); + + // a simple psuedo-random series which does not rely on rand() and friends + v[0] = 0; + for (int i = 1; i < max_size; ++i) + v[i] = (v[i-1] + 110211473) * 745988807; + + start_counters(time, resource); + std::stable_sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "random", time, resource); + + return 0; +}