-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Improve performance of toMap() && parseAttributes() #5854
Improve performance of toMap() && parseAttributes() #5854
Comments
@Reinmar I faced the very same thing when testing further tweaks for #4504. Also you can reuse our isIterable util function. Another relatively expensive but easy to improve (performance-wise) bit was prefix matching using a regexp (which happens in many different view and model types). You can check prefix by simply using |
I'm trying to understand why/where /**
* Sets values of attributes on a {@link module:engine/model/item~Item model item}
* or on a {@link module:engine/model/range~Range range}.
*
* writer.setAttributes( {
* bold: true,
* italic: true
* }, range );
*
* @param {Object} attributes Attributes keys and values.
* @param {module:engine/model/item~Item|module:engine/model/range~Range} itemOrRange
* Model item or range on which the attributes will be set.
*/
setAttributes( attributes, itemOrRange ) {
for ( const [ key, val ] of toMap( attributes ) ) {
this.setAttribute( key, val, itemOrRange );
}
} After changing this to This makes me think if we don't overuse The But now for |
I guess that if we want to simply iterate over object props then the for-in loop will always be the fastest way 😅 |
I pushed to ckeditor5 a branch on which I was testing the performance: #3767 (comment). |
One additional note – when doing any performance-oriented work, do always start from a real issue. There are thousands of ways how we could improve our code as most of it wasn't written with perf in mind and certainly wasn't tested for that. But from my experience, real issues point you to completely different places than intuition. Also, it's very often that there's no way to improve the performance of a certain code by optimizing that code. Instead, we should be looking at how to not execute it at all or do that far less frequently. This is all quite well visible in the flame chart combined with some additional simple tests. So, really, start there. |
Other: Improved `toMap` method performance. This results in improved editor data processing speed. Closes ckeditor/ckeditor5#5854.
Other: Improved `parseAttributes` function performance. This results in improved editor data processing speed. Closes ckeditor/ckeditor5#5854.
EDIT: I extended this ticket to cover not only the
toMap()
implementation in model/Node, but alsoparseAttributes()
in view/Element which has the same issue (IIRC).This function is called extremely frequently and becomes the most time-consuming thing in #4504 and setting editor data with complex content.
99% of time inside it is spent on
isPlainObject()
. My guess is that it's so slow because it uses something likeObject.prototype.toString.apply( obj ) == '...'
to check what we've got inside and perhaps cover some other cases that we don't really need intoMap()
.According to the docs,
toMap()
should work with objects or iterables. I'd actually check with what kind of objects it's really executed because I also expect to see maps and arrays (so, iterables too), but we should make sure we're not breaking it for them.One thing I noticed is that
toMap()
's tests don't actually cover the iterables case 🤦♂ . I was able to write an implementation that passes all tests but breaks in the engine.So, this is perhaps more or less what we need:
This allowed me to get from 8s to 6s when loading complex data and from 1843ms to 693ms when removing attributes from content taken from https://github.com/ckeditor/ckeditor5-remove-format/issues/7.
The text was updated successfully, but these errors were encountered: