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

Stop Sort from comparing identical objects #2621

Merged
merged 1 commit into from
Jul 9, 2018

Conversation

ChrisJefferson
Copy link
Contributor

Some comparators do not handle comparing identical objects, which
occurs when we compare values with the pivot during quicksort.

This fixes #2618.

The fundamental problem is that we compare values with the pivot when doing quicksort partitioning.

Just in case anyone thinks "Wait, this is stupid. Can't I just move the quicksort pivot out of the way, maybe to the start of the array?", I warn you that that is move difficult than it sounds -- by moving the pivot to the start of the array (and then later to the pivot place), you then break that the "middle value from first, last, middle" is picking (reasonably) random elements of the array, which makes quicksort hit it's worst cases much more often.

This can be fixed (you have never pivot using elements of the array where you have put special things)- but then you need to be careful with array length, and this tends to make the pdqsort algorithm less efficient, as bits of the array get suffled. I did this long ago in g++ and messed it up a couple of times, so don't really want to go through it again if it's not absolutely required :)

In short, if you want to try to do this better, be prepared to carefully benchmark a bunch of cases (array nearly sorted and array nearly reversed are the main two).

@codecov
Copy link

codecov bot commented Jul 4, 2018

Codecov Report

Merging #2621 into master will decrease coverage by <.01%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #2621      +/-   ##
==========================================
- Coverage   75.12%   75.11%   -0.01%     
==========================================
  Files         479      479              
  Lines      242200   242204       +4     
==========================================
- Hits       181956   181940      -16     
- Misses      60244    60264      +20
Impacted Files Coverage Δ
src/sortbase.h 97.6% <100%> (+0.05%) ⬆️
lib/groebner.gi 84.15% <0%> (-1.97%) ⬇️
src/iostream.c 62.35% <0%> (-1.15%) ⬇️
lib/list.gi 70.66% <0%> (-0.07%) ⬇️
hpcgap/lib/hpc/stdtasks.g 63.93% <0%> (+0.51%) ⬆️

src/sortbase.h Outdated
// This can occur either because the original list had identical
// objects, or when comparing against the pivot in quicksort.
#define SORT_COMP_CHECK_EQ PREFIXNAME(SortCompCheckEqObj)
Int SORT_COMP_CHECK_EQ(SORT_FUNC_ARGS, Obj a, Obj b) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this perhaps be marked static and/or inline?

Copy link
Member

@markuspf markuspf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me (assuming @fingolfin question is answered).

Some comparators do not handle comparing identical objects, which
occurs when we compare values with the pivot during quicksort.
@markuspf markuspf merged commit eb6a367 into gap-system:master Jul 9, 2018
@ChrisJefferson ChrisJefferson deleted the sort-fix branch August 20, 2018 10:05
@fingolfin fingolfin added topic: kernel release notes: not needed PRs introducing changes that are wholly irrelevant to the release notes labels Sep 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release notes: not needed PRs introducing changes that are wholly irrelevant to the release notes topic: kernel
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sort sometimes compares an object to itself
3 participants