-
Notifications
You must be signed in to change notification settings - Fork 858
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
Make "hybrid" sort algorithm more robust. #360
Conversation
Add bounds checking so that we don't make so many assumptions about how the comparator behaves. Make the "median of three" algorithm actually take the median of three.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except for minor suggestions, this PR looks good to me. I've tried to break sorting again with some weird/broken comparators, but couldn't.
private static int median(int n1, int n2, int n3) | ||
/* | ||
Return the index of the smallest of three elements in the specified array range -- the | ||
first, the last, and the one in the middle. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct? From my reading median()
returns the index of the median of three elements (start, end and in the middle), not the smallest in range.
return 0; | ||
}); | ||
|
||
// Torture tests devised by @sainen and @bensummers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, but I'd say that attribution isn't in necessary/useful here. It's just a test, plus comparator itself comes from underscore. (And it's sainaen. 🙂 )
if (a < b || b === void 0) return -1; | ||
} | ||
return left.index < right.index ? -1 : 1; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since both these ‘torture’ cases are basically the same, how about replacing one of them with something different that also throws currently?
Like,
// should work ok, comparator is similar to the underscore's one
sortAndCompare([1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], function (a, b) { return a >= b ? 1 : -1; });
// weird comparator, array may not be sorted, but shouldn't fail/throw
assertDoesNotThrow(function () {
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1].sort(function (a, b) { return -1; });
});
// yet another weird comparator, again shouldn't fail/throw
assertDoesNotThrow(function () {
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1].sort(function (a, b) { return 1; });
});
Thanks for the review and suggestions! I kind of think that if someone sends us code and they're not going to be part of the Git commit then I should credit them ;-) I'll merge this soon. |
Add bounds checking so that we don't make so many assumptions about
how the comparator behaves.
Make the "median of three" algorithm actually take the median
of three.