@@ -26,10 +26,19 @@ can't fallback to a O(n log² n) algorithm when there isn't enough extra heap me
2626 type such as ` void ` .
2727
2828
29+ Merging sorted ranges efficiently is an important part of the TimSort algorithm. This library exposes its merge
30+ algorithm in the public API. According to the benchmarks, ` gfx::timmerge ` is slower than ` std::inplace_merge ` on
31+ heavily/randomly overlapping subranges of simple elements, but it is faster for complex elements such as ` std::string `
32+ and on sparsely overlapping subranges. ` gfx::timmerge ` should be usable as a drop-in replacement for
33+ ` std::inplace_merge ` , with the difference that it can't fallback to a O(n log n) algorithm when there isn't enough
34+ extra heap memory available. Like ` gfx::timsort ` , ` gfx::timmerge ` can take a projection function and avoids using the
35+ postfix ` ++ ` or ` -- ` operators.
36+
37+
2938The full list of available signatures is as follows (in namespace ` gfx ` ):
3039
3140``` cpp
32- // Overloads taking a pair of iterators
41+ // timsort overloads taking a pair of iterators
3342
3443template <typename RandomAccessIterator>
3544void timsort (RandomAccessIterator const first, RandomAccessIterator const last);
@@ -42,7 +51,7 @@ template <typename RandomAccessIterator, typename Compare, typename Projection>
4251void timsort(RandomAccessIterator const first, RandomAccessIterator const last,
4352 Compare compare, Projection projection);
4453
45- // Overloads taking a range
54+ // timsort overloads taking a range
4655
4756template <typename RandomAccessRange >
4857void timsort(RandomAccessRange &range);
@@ -52,6 +61,20 @@ void timsort(RandomAccessRange &range, Compare compare);
5261
5362template <typename RandomAccessRange, typename Compare, typename Projection>
5463void timsort(RandomAccessRange &range, Compare compare, Projection projection);
64+
65+ // timmerge overloads
66+
67+ template <typename RandomAccessIterator >
68+ void timmerge(RandomAccessIterator first, RandomAccessIterator middle,
69+ RandomAccessIterator last);
70+
71+ template <typename RandomAccessIterator, typename Compare>
72+ void timmerge(RandomAccessIterator first, RandomAccessIterator middle,
73+ RandomAccessIterator last, Compare compare);
74+
75+ template <typename RandomAccessIterator, typename Compare, typename Projection>
76+ void timmerge(RandomAccessIterator first, RandomAccessIterator middle,
77+ RandomAccessIterator last, Compare compare, Projection projection);
5578```
5679
5780## EXAMPLE
@@ -102,7 +125,7 @@ conan install timsort/2.0.2
102125
103126## DIAGNOSTICS & INFORMATION
104127
105- A few configuration macros allow gfx::timsort to emit diagnostic, which might be helpful to diagnose issues:
128+ A few configuration macros allow ` gfx::timsort ` and ` gfx::timmerge ` to emit diagnostic, which might be helpful to diagnose issues:
106129* Defining ` GFX_TIMSORT_ENABLE_ASSERT ` inserts assertions in key locations in the algorithm to avoid logic errors.
107130* Defining ` GFX_TIMSORT_ENABLE_LOG ` inserts logs in key locations, which allow to follow more closely the flow of the algorithm.
108131
@@ -130,7 +153,7 @@ built with CMake:
130153Benchmarks are available in the ` benchmarks ` subdirectory, and can be constructed directly by passing ` BUILD_BENCHMARKS=ON `
131154variable to CMake during the configuration step.
132155
133- Example output (timing scale: sec.):
156+ Example bench_sort output (timing scale: sec.):
134157
135158 c++ -v
136159 Apple LLVM version 7.0.0 (clang-700.0.72)
@@ -171,3 +194,29 @@ Example output (timing scale: sec.):
171194 std::sort 0.402458
172195 std::stable_sort 2.436326
173196 timsort 0.298639
197+
198+ Example bench_merge output (timing scale: milliseconds; omitted detailed results for different
199+ middle iterator positions, reformatted to improve readability):
200+
201+ c++ -v
202+ Using built-in specs.
203+ ...
204+ Target: x86_64-pc-linux-gnu
205+ ...
206+ gcc version 10.2.0 (GCC)
207+ c++ -I ../include -Wall -Wextra -g -DNDEBUG -O2 -std=c++11 bench_merge.cpp -o bench_merge
208+ ./bench_merge
209+ size 100000
210+ element type\algorithm: std::inplace_merge timmerge
211+ RANDOMIZED SEQUENCE
212+ [int] approx. average 33.404430 37.047990
213+ [std::string] approx. average 324.964249 210.297207
214+ REVERSED SEQUENCE
215+ [int] approx. average 11.441404 4.017482
216+ [std::string] approx. average 305.649503 114.773898
217+ SORTED SEQUENCE
218+ [int] approx. average 4.291098 0.105571
219+ [std::string] approx. average 158.238114 0.273858
220+
221+ Detailed bench_merge results for different middle iterator positions can be found at
222+ https://github.com/timsort/cpp-TimSort/wiki/Benchmark-results
0 commit comments