Computed.sort 10 times slower than sortBy

Hello

In my project I have an array with a few thousands elements which needs to be sorted. My first attempt was to use

dataSorting: ['property'],
dataSorted: Ember.computed.sort('data', 'dataSorting')

but I was disappointed with the performance. It took around 30 seconds to sort and display the array. My next attempt was to use

dataSorted: Ember.computed('data', function() {
  return this.get('data').sortBy('property');
})

and this solution takes only around 500 milliseconds to sort and display.

I was unsure if something else in my project is causing this behavior and I created a simple Ember Twiddle app to show the performance difference: https://ember-twiddle.com/5ed7c167f51d1532dcc08ddf0b271771 Perhaps my performance measurement is not totally accurate but it shows a difference between the two sorting methods.

Do I use Ember.computed.sort incorrectly or is it meant only for small arrays?

Thanks

3 Likes

maybe some specific implementation

for instance in my research I found out that using key in each helper speeds up rendering twice. Even if you have plain array.

e.g {{#each db.lastSample.topFiveQueries key="@index" as |query|}}

The underlying propertySort function does a lot more than native sortBy. Probably thats why there is a difference. But I agree that difference is non-trivial.

Thanks for your replies.

I assumed that the computed property does more under the hood and I looked through the code in the link you sent. But I don’t see any benefits and will stick with the sortBy() function.

I’ve common around this old thread and was quite shocked. Investigated the issue a little bit and want to share my findings:

  • Issue has been fixed in Ember 2.14. Using Ember 2.10 up to 2.13 I’m seeing ~800ms for computed.sort. After upgrading to 2.14 or later rendering time drops to ~180ms. So it’s five times faster. It’s still slower than {{sortBy}} which takes ~35ms for me on all tested versions.
  • The method to measure performance is not quite good. Switching the order of the components has a huge impact on metrics. {{sort-by}} is slower (~200ms) than {{computed-sort}} (~150ms) if executed first. However the difference is not that much as in the other order.

I’ve implemented another approach to measure the performance, which should be more accurate: Ember Twiddle It shows that the simple computed property using sortBy array method is not much faster than sort macro.

1 Like

The remaining performance difference is there because your two examples don’t do the same thing.

This one will only recompute if you replace the entire data array:

dataSorted: Ember.computed('data', function() {
  return this.get('data').sortBy('property');
})

This one will recompute if you replace data, add items to it, remove items from it, edit the dataSorting property, or edit the field inside dataSorting (currently property) on any of the items in the array:

dataSorting: ['property'],
dataSorted: Ember.computed.sort('data', 'dataSorting')

So basically Ember.computed.sort exists for when you actually want to watch a ton of stuff and react to those changes. If you don’t need to watch all that stuff, definitely just do your own Array sort.

The different performance is not caused by observing more properties. I’ve implemented a complexCP (bad naming so, all of them are computed properties…), which “recomputes if you replace data, add items to it, remove items from it, edit the dataSorting property, or edit the field inside dataSorting (currently property) on any of the items in the array”. I don’t see any performance difference compared to simpleCP: Ember Twiddle

I assume the perf difference is caused by supporting to sort the array by multiple fields but did not had a deeper look in the source code yet. But in my opinion that perf difference is so little since Ember 2.14 that it doesn’t matter for most real-wold-scenarios. Using sort macro the code is way more readable, which is more important to me.

1 Like