Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.11.0 #191

Merged
merged 57 commits into from Jul 24, 2021
Merged

Release 1.11.0 #191

merged 57 commits into from Jul 24, 2021

Conversation

Morwenn
Copy link
Owner

@Morwenn Morwenn commented Jul 24, 2021

No description provided.

The default version on the Ubuntu 16.04 image was change to clang 9.0.1,
change to that for now, investigate installing older versions later.
Monobound binary search is a variation on standard binary search
proposed by @scandum: instead of computing the exact size of the next
partition where to look for an element, it always recurses in a
partition of size n-n/2. This change means that a few redudant
operations are performed when the size isn't a power of 2, but it also
means that the generated code can be much smaller.

Here we use it for probe::enc when the comparison and projection
functions are likely branchless: benchmarks showed that tis measure of
presortedness becomes up to 40% when measuring the presortedness of a
std::vector<double>. The gain is sufficient to switch to monobound
binary search for the cases where it is an obvious improvement.
probe::enc still uses a standard binary search the rest of the time.
The attribute isn't C++14, warns in Clang because of that, is not in the
public interface, and unlike empty() it's obvious that the function is
not modifying the collection, so it's not worth adding more macros for
that single function.
The algorithm was using upper_bound in the inner loop, which was
recomputing the size of the range where to insert the new element at
each iteration. This changes the algorithm which now manages the size
itself and feeds it to upper_bound_n instead, saving O(n) operations per
iteration.
This bug basically made the algorithm unusable, and slow when it
actually happened to work. This commit fixes the bug and uses binary search
instead of linear search to perform no more than O(n log n) comparisons.
Many operations on list nodes only act on the iteration and the
relinking, and the specific type of the list node isn't required for
those. This creates a new non-template list_node_base class with the
pointers prev & next, and changes many operations to accept a pointer to
a list_node_base instead of a node_list<T>.

The major gain is that it allows to use a list_node_base for sentinel
nodes instead of a full list_node<T>, saving sizeof(T) space for every
list - space that was never used anyway. This means that the memory cost
of melsort is reduced by up to sqrt(n)*sizeof(T) while that of slbasort
is reduced by up to 2log(n)*sizeof(T).
Add "lower is better" to the legend of the relevant axis in each plot
drawing script.
This allows to test every existing distribution in the benchmark suite
(save maybe the ones that generate negative numbers) with std::string in
a way that makes the comparison expensive: the constructed string is
always 50-character long and ends with the characters corresponding to
the digits of the input number.
stable_compare was calling std::forwarf twice on its parameters, and a
few other functions were calling std::move instead of std::forward on
forwardinf references. It probably hadn't caused any issue so far, but
those issues are still best fixed.
Really similar to std::sort, but with the following properties: it's got
a fixed capacity determined at construction time, and it is not movable.
Unlike std::vector it allows to store immovable types.

We use that new class everywhere it makes sense, simplifying a bunch of
std::unique_ptr/destroy_n thingies.

This commit also changes cartesian_tree_sort quite a bit and fixes a
potential bug in its destructor: when an exception was thrown during the
construction of the Cartesian tree, destroy_at was called on every
allocated element instead of every constructed element.
Morwenn added 27 commits May 16, 2021 23:56
WikiSort is just *a* block sort and we already have grail_sort in the
library which is another block sort which works differently. Therefore
reserving the name block_sort to wiki feels a bit misleading, especially
with the growing body of block sorts that appear nowadays.
Also abbreviate to CEs instead of CEUs to match the abbreviation used by
the SorterHunter project, which is currently the main source of
information used for the sorting networks.

Some drive-by documentation fixes.
@Morwenn Morwenn merged commit 4dcd62b into master Jul 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant