-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Sorted collection: use binary search to insert items #3243
Conversation
(in regular iterator case)
The comparator case is pretty important to me - should I open a ticket over at underscore to have _.sortedIndex extended to include support for comparators? |
Can we get a JSPerf along with this change? (this is how it used to work) |
It actually turns out to be breaking as var array = [{a: NaN}, {a: NaN}, {a: {}}, {a: 1}, {a: 2}];
_.sortedIndex(array, {a: 3}, 'a'); // => 0
var sorted = _.sortBy(array.concat({a: 3}), 'a');
_.findIndex(sorted, {a: 3}); // => 5 |
If the pull request #3207 is merged, then the Furthermore, as I have mentioned in another issue, one thing that you may want to consider is whether or not your changes will compromise performance in the condition that the As I discussed, if you are adding u items to a collection of ultimately n items, the current implementation will take O(n lg n) time but a binary insertion of each model will take O(u n) time. If u is 1, then the current approach could be better, but if u very large it is optimal. The difference in time for many models will be far worse if this is the approach that is taken, and the improvements offered for individual items are unlikely to be noticed - unless many items will be added separately, in which case we should recommend that users group them together. |
I don't know the performance impact of inserting items in the middle of a JS list. If insertion is an O(1) operation, then binary insertion sort is O(u log n), if it is slow, then you wind up with O(u n). I had been assuming that it was negligible. Either way, we could do sorting all-at-once with the .sort() method if there are more than one element being added, and sort one-at-a-time if there is only one. |
Insertion will almost certainly be O(n), see stackoverflow. It may be possible to estimate on the fly what insertion implementation will be faster, and I am not necessarily opposed to the idea. However, it would certainly make the code more complicated and increase the file size. This decision is a tradeoff between those issues and the performance gains. My immediate thoughts are that if users are so concerned with the speed of their code to care, then they could easily speed it up themselves by either pausing sorting while items are added and then explicitly calling |
@dts run time analysis can be sketchy for this sort of thing... The current approach is technically |
One must also consider that there may be performance side-effects of emitting a What we currently convey with a For these reasons, I'm currently using Backbone.VirtualCollection in order to add this binary search functionality for insertions. This must of course be layered over a standard unordered Backbone Collection. This solution is working well for me, but I consider the semantic issue above to be a design defect -- albeit one that users are likely relying upon. |
If it's breaking still, let's leave this be for now... As I said up top — sortedIndex insert at position is how this used to be implemented. We changed to sort'ing for some reason at some point. |
Use
_.sortedIndex
to determine the new position of an element when inserting items in the simpleiterator
case. Continue delegating tosort
for the comparator case.Resolves #3242