Bug 1843946 Comment 0 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

We can improve innerHTML performance on content which contains elements with `class="one two three four"` (which is the case on speedometer3) by making the `MiscContainer` of `eAtomArray` attributes refcounted, and by caching these `MiscContainer`s globally. This optimization mirrors Chrome's `SpaceSplitString` optimization with its [global cache](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/space_split_string.cc;l=171-174;drc=37a22a50b5deed732d05c1ff242dba74b8b69266).

Here's a profile of 33 iterations of the TodoMVC-jQuery subtest, focused on `nsHtml5TreeOperation::SetHTMLElementAttributes`: https://share.firefox.dev/3Dk2cvg

It shows multiple problems:

 - Inside `Element::SetAttrAndNotify`, a lot of time is taken up by `valueForAfterSetAttr`, specifically by allocating and freeing the copy of the atom array.
 - We spend a fair amount of time in `ParseAttribute` allocating atom arrays and atomizing strings.

Making the `MiscContainer` for `eAtomArray` refcounted makes the copy basically free, so it eliminates the time in `SetTo` and `~nsAttrValue`. And by having a global cache we can reduce the time we spend atomizing individual class names. We'll just be atomizing the full attribute value, in order to have a faster cache lookup and in order to avoid a string copy.

If copying the class attribute is cheaper, this also speeds up `mozilla::ServoElementSnapshot::AddAttrs`, which is called when somebody mutates the classList of an element.
We can improve innerHTML performance on content which contains elements with `class="one two three four"` (which is the case on speedometer3) by making the `MiscContainer` of `eAtomArray` attributes refcounted, and by caching these `MiscContainer`s globally. This optimization mirrors Chrome's `SpaceSplitString` optimization with its [global cache](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/space_split_string.cc;l=171-174;drc=37a22a50b5deed732d05c1ff242dba74b8b69266).

Here's a profile of 33 iterations of the TodoMVC-jQuery subtest, focused on `nsHtml5TreeOperation::SetHTMLElementAttributes`: https://share.firefox.dev/3Dk2cvg

It shows multiple problems:

 - Inside `Element::SetAttrAndNotify`, a lot of time is taken up by `valueForAfterSetAttr`, specifically by allocating and freeing the copy of the atom array (inside `SetTo` and `~nsAttrValue`).
 - We spend a fair amount of time in `ParseAttribute` allocating atom arrays and atomizing strings.

Making the `MiscContainer` for `eAtomArray` refcounted makes the copy basically free, so it eliminates the time in `SetTo` and `~nsAttrValue`. And by having a global cache we can reduce the time we spend atomizing individual class names. We'll just be atomizing the full attribute value, in order to have a faster cache lookup and in order to avoid a string copy.

If copying the class attribute is cheaper, this also speeds up `mozilla::ServoElementSnapshot::AddAttrs`, which is called when somebody mutates the classList of an element.
We can improve innerHTML performance on content which contains elements with `class="one two three four"` (which is the case on speedometer3) by making the `MiscContainer` of `eAtomArray` attributes refcounted, and by caching these `MiscContainer`s globally. This optimization mirrors Chrome's `SpaceSplitString` optimization with its [global cache](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/space_split_string.cc;l=171-174;drc=37a22a50b5deed732d05c1ff242dba74b8b69266).

Here's a profile of 33 iterations of the TodoMVC-jQuery subtest, focused on `nsHtml5TreeOperation::SetHTMLElementAttributes`: https://share.firefox.dev/3Dk2cvg

It shows multiple problems:

 - Inside `Element::SetAttrAndNotify`, a lot of time is taken up by `valueForAfterSetAttr`, specifically by allocating and freeing the copy of the atom array (inside `SetTo` and `~nsAttrValue`).
 - We spend a fair amount of time in `ParseAttribute` allocating atom arrays and atomizing strings.

Making the `MiscContainer` for `eAtomArray` refcounted makes the copy basically free, so it eliminates the time in `SetTo` and `~nsAttrValue`. And by having a global cache we can reduce the time we spend atomizing individual class names. We'll just be atomizing the full attribute value, in order to have a faster cache lookup and in order to avoid a string copy. And by sharing the atom array between elements, we reduce the number of atom array allocations.

If copying the class attribute is cheaper, this also speeds up `mozilla::ServoElementSnapshot::AddAttrs`, which is called when somebody mutates the classList of an element.
We can improve innerHTML performance on content which contains elements with `class="one two three four"` (which is the case on speedometer3) by making the `MiscContainer` of `eAtomArray` attributes refcounted, and by caching these `MiscContainer`s globally. This optimization mirrors Chrome's `SpaceSplitString` optimization with its [global cache](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/space_split_string.cc;l=171-174;drc=37a22a50b5deed732d05c1ff242dba74b8b69266).

Here's a profile of 33 iterations of the TodoMVC-jQuery subtest, focused on `nsHtml5TreeOperation::SetHTMLElementAttributes`: https://share.firefox.dev/3Dk2cvg

It shows multiple problems:

 - Inside `Element::SetAttrAndNotify`, a lot of time is taken up by `valueForAfterSetAttr`, specifically by allocating and freeing the copy of the atom array (inside `SetTo` and `~nsAttrValue`).
 - We spend a fair amount of time in `ParseAttribute` allocating atom arrays and atomizing strings.

Making the `MiscContainer` for `eAtomArray` refcounted makes the copy basically free, so it eliminates the time in `SetTo` and `~nsAttrValue`. And by having a global cache we can reduce the time we spend atomizing individual class names. We'll just be atomizing the full attribute value, in order to have a faster cache lookup and in order to avoid a string copy. And by sharing the atom array between elements, we reduce the number of atom array allocations.

If copying the class attribute is cheaper, this also speeds up `ServoElementSnapshot::AddAttrs`, which is called when somebody mutates the classList of an element.
We can improve innerHTML performance on content which contains elements with multiple class names, i.e. `class="one two three four"`, by making the `MiscContainer` of `eAtomArray` attributes refcounted, and by caching these `MiscContainer`s globally. This optimization mirrors Chrome's `SpaceSplitString` optimization with its [global cache](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/space_split_string.cc;l=171-174;drc=37a22a50b5deed732d05c1ff242dba74b8b69266).  This improves innerHTML times on Speedometer 3.

Here's a profile with current Firefox Nightly, of 33 iterations of the TodoMVC-jQuery subtest, focused on `nsHtml5TreeOperation::SetHTMLElementAttributes`: https://share.firefox.dev/3Dk2cvg

It shows multiple problems:

 - Inside `Element::SetAttrAndNotify`, a lot of time is taken up by `valueForAfterSetAttr`, specifically by allocating and freeing the copy of the atom array (inside `SetTo` and `~nsAttrValue`).
 - We spend a fair amount of time in `ParseAttribute` allocating atom arrays and atomizing strings.

Making the `MiscContainer` for `eAtomArray` refcounted makes the copy basically free, so it eliminates the time in `SetTo` and `~nsAttrValue`. And by having a global cache we can reduce the time we spend atomizing individual class names. We'll just be atomizing the full attribute value, in order to have a faster cache lookup and in order to avoid a string copy. And by sharing the atom array between elements, we reduce the number of atom array allocations.

If copying the class attribute is cheaper, this also speeds up `ServoElementSnapshot::AddAttrs`, which is called when somebody mutates the classList of an element.
We can improve innerHTML performance on content which contains elements with multiple class names, i.e. `class="one two three four"`, by making the `MiscContainer` of `eAtomArray` attributes refcounted, and by caching these `MiscContainer`s globally. This optimization mirrors Chrome's `SpaceSplitString` optimization with its [global cache](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/space_split_string.cc;l=171-174;drc=37a22a50b5deed732d05c1ff242dba74b8b69266).  This improves innerHTML times on Speedometer 3.

Here's a profile with current Firefox Nightly, of 33 iterations of the TodoMVC-jQuery subtest, focused on `nsHtml5TreeOperation::SetHTMLElementAttributes`: https://share.firefox.dev/3Dk2cvg

I noticed these things in the profiles:

 - Inside `Element::SetAttrAndNotify`, a lot of time is taken up by `valueForAfterSetAttr`, specifically by allocating and freeing the copy of the atom array (inside `SetTo` and `~nsAttrValue`).
 - We spend a fair amount of time in `ParseAttribute` allocating atom arrays and atomizing strings.

Making the `MiscContainer` for `eAtomArray` refcounted makes the copy basically free, so it eliminates the time in `SetTo` and `~nsAttrValue`. And by having a global cache we can reduce the time we spend atomizing individual class names. We'll just be atomizing the full attribute value, in order to have a faster cache lookup and in order to avoid a string copy. And by sharing the atom array between elements, we reduce the number of atom array allocations.

If copying the class attribute is cheaper, this also speeds up `ServoElementSnapshot::AddAttrs`, which is called when somebody mutates the classList of an element.
We can improve innerHTML performance on content which contains elements with multiple class names, i.e. `class="one two three four"`, by making the `MiscContainer` of `eAtomArray` attributes refcounted, and by caching these `MiscContainer`s globally. This optimization mirrors Chrome's `SpaceSplitString` optimization with its [global cache](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/space_split_string.cc;l=171-174;drc=37a22a50b5deed732d05c1ff242dba74b8b69266).  This improves innerHTML times on Speedometer 3.

Here's a profile with current Firefox Nightly, of 33 iterations of the TodoMVC-jQuery subtest, focused on `nsHtml5TreeOperation::SetHTMLElementAttributes`: https://share.firefox.dev/3Dk2cvg

I noticed these things in the profile:

 - Inside `Element::SetAttrAndNotify`, a lot of time is taken up by `valueForAfterSetAttr`, specifically by allocating and freeing the copy of the atom array (inside `SetTo` and `~nsAttrValue`).
 - We spend a fair amount of time in `ParseAttribute` allocating atom arrays and atomizing strings.

Making the `MiscContainer` for `eAtomArray` refcounted makes the copy basically free, so it eliminates the time in `SetTo` and `~nsAttrValue`. And by having a global cache we can reduce the time we spend atomizing individual class names. We'll just be atomizing the full attribute value, in order to have a faster cache lookup and in order to avoid a string copy. And by sharing the atom array between elements, we reduce the number of atom array allocations.

If copying the class attribute is cheaper, this also speeds up `ServoElementSnapshot::AddAttrs`, which is called when somebody mutates the classList of an element.

Back to Bug 1843946 Comment 0