No subject


Mon Jan 28 08:41:14 PST 2013


8622">r148622</a> by &lt;cevans at chromium.org&gt;.

The previous version had a couple of issues:
- Incurred new WTF::Vector::operator[] checks.
- Had a branch in _every_ loop iteration that checked whether the storage=
 was Vector or array[] backed.

Both these issues are fixed, and CloneNodes.html seems reliably at +2%.
I also believe GetElement.html is maybe +1%.

For WebKit, also applied the same optimization to getAttributeItemIndex()=
.

* dom/Element.h:
(WebCore::ElementData::attributeBase):
(WebCore::ElementData::getAttributeItemIndex):
(WebCore::ElementData::getAttributeItem):
(WebCore::ElementData::attributeItem):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href=3D"#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeL=
og</a></li>
<li><a href=3D"#trunkSourceWebCoredomElementh">trunk/Source/WebCore/dom/E=
lement.h</a></li>
</ul>

</div>
<div id=3D"patch">
<h3>Diff</h3>
<a id=3D"trunkSourceWebCoreChangeLog"></a>
<div class=3D"modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (1489=
60 =3D> 148961)</h4>
<pre class=3D"diff"><span>
<span class=3D"info">--- trunk/Source/WebCore/ChangeLog	2013-04-23 12:07:=
57 UTC (rev 148960)
+++ trunk/Source/WebCore/ChangeLog	2013-04-23 14:21:05 UTC (rev 148961)
</span><span class=3D"lines">@@ -1,3 +1,27 @@
</span><ins>+2013-04-23  Andreas Kling  &lt;akling at apple.com&gt;
+
+        Speed up ElementData::getAttributeItem(), which is hot.
+        &lt;http://webkit.org/b/115031&gt;
+
+        Reviewed by Antti Koivisto.
+
+        From Blink r148622 by &lt;cevans at chromium.org&gt;.
+
+        The previous version had a couple of issues:
+        - Incurred new WTF::Vector::operator[] checks.
+        - Had a branch in _every_ loop iteration that checked whether th=
e storage was Vector or array[] backed.
+
+        Both these issues are fixed, and CloneNodes.html seems reliably =
at +2%.
+        I also believe GetElement.html is maybe +1%.
+
+        For WebKit, also applied the same optimization to getAttributeIt=
emIndex().
+
+        * dom/Element.h:
+        (WebCore::ElementData::attributeBase):
+        (WebCore::ElementData::getAttributeItemIndex):
+        (WebCore::ElementData::getAttributeItem):
+        (WebCore::ElementData::attributeItem):
+
</ins><span class=3D"cx"> 2013-04-23  Antoine Quint  &lt;graouts at apple.co=
m&gt;
</span><span class=3D"cx">=20
</span><span class=3D"cx">         Initial advance of text runs should be=
 taken into account
</span></span></pre></div>
<a id=3D"trunkSourceWebCoredomElementh"></a>
<div class=3D"modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.h (=
148960 =3D> 148961)</h4>
<pre class=3D"diff"><span>
<span class=3D"info">--- trunk/Source/WebCore/dom/Element.h	2013-04-23 12=
:07:57 UTC (rev 148960)
+++ trunk/Source/WebCore/dom/Element.h	2013-04-23 14:21:05 UTC (rev 14896=
1)
</span><span class=3D"lines">@@ -110,6 +110,7 @@
</span><span class=3D"cx">     friend class SVGElement;
</span><span class=3D"cx"> #endif
</span><span class=3D"cx">=20
</span><ins>+    const Attribute* attributeBase() const;
</ins><span class=3D"cx">     const Attribute* getAttributeItem(const Ato=
micString&amp; name, bool shouldIgnoreAttributeCase) const;
</span><span class=3D"cx">     size_t getAttributeItemIndexSlowCase(const=
 AtomicString&amp; name, bool shouldIgnoreAttributeCase) const;
</span><span class=3D"cx">=20
</span><span class=3D"lines">@@ -940,6 +941,13 @@
</span><span class=3D"cx">     return m_arraySize;
</span><span class=3D"cx"> }
</span><span class=3D"cx">=20
</span><ins>+inline const Attribute* ElementData::attributeBase() const
+{
+    if (m_isUnique)
+        return static_cast&lt;const UniqueElementData*&gt;(this)-&gt;m_a=
ttributeVector.data();
+    return static_cast&lt;const ShareableElementData*&gt;(this)-&gt;m_at=
tributeArray;
+}
+
</ins><span class=3D"cx"> inline const StylePropertySet* ElementData::pre=
sentationAttributeStyle() const
</span><span class=3D"cx"> {
</span><span class=3D"cx">     if (!m_isUnique)
</span><span class=3D"lines">@@ -957,8 +965,9 @@
</span><span class=3D"cx">=20
</span><span class=3D"cx"> inline size_t ElementData::getAttributeItemInd=
ex(const QualifiedName&amp; name) const
</span><span class=3D"cx"> {
</span><del>-    for (unsigned i =3D 0; i &lt; length(); ++i) {
-        if (attributeItem(i)-&gt;name().matches(name))
</del><ins>+    const Attribute* attributes =3D attributeBase();
+    for (unsigned i =3D 0, count =3D length(); i &lt; count; ++i) {
+        if (attributes[i].name().matches(name))
</ins><span class=3D"cx">             return i;
</span><span class=3D"cx">     }
</span><span class=3D"cx">     return notFound;
</span><span class=3D"lines">@@ -968,15 +977,14 @@
</span><span class=3D"cx"> // can tune the behavior (hasAttribute is case=
 sensitive whereas getAttribute is not).
</span><span class=3D"cx"> inline size_t ElementData::getAttributeItemInd=
ex(const AtomicString&amp; name, bool shouldIgnoreAttributeCase) const
</span><span class=3D"cx"> {
</span><del>-    unsigned len =3D length();
</del><ins>+    const Attribute* attributes =3D attributeBase();
</ins><span class=3D"cx">     bool doSlowCheck =3D shouldIgnoreAttributeC=
ase;
</span><ins>+    const AtomicString&amp; caseAdjustedName =3D shouldIgnor=
eAttributeCase ? name.lower() : name;
</ins><span class=3D"cx">=20
</span><del>-    const AtomicString caseAdjustedName =3D shouldIgnoreAttr=
ibuteCase ? name.lower() : name;
</del><span class=3D"cx">     // Optimize for the case where the attribut=
e exists and its name exactly matches.
</span><del>-    for (unsigned i =3D 0; i &lt; len; ++i) {
-        const Attribute* attribute =3D attributeItem(i);
-        if (!attribute-&gt;name().hasPrefix()) {
-            if (caseAdjustedName =3D=3D attribute-&gt;localName())
</del><ins>+    for (unsigned i =3D 0, count =3D length(); i &lt; count; =
++i) {
+        if (!attributes[i].name().hasPrefix()) {
+            if (caseAdjustedName =3D=3D attributes[i].localName())
</ins><span class=3D"cx">                 return i;
</span><span class=3D"cx">         } else
</span><span class=3D"cx">             doSlowCheck =3D true;
</span><span class=3D"lines">@@ -989,9 +997,10 @@
</span><span class=3D"cx">=20
</span><span class=3D"cx"> inline const Attribute* ElementData::getAttrib=
uteItem(const QualifiedName&amp; name) const
</span><span class=3D"cx"> {
</span><del>-    for (unsigned i =3D 0; i &lt; length(); ++i) {
-        if (attributeItem(i)-&gt;name().matches(name))
-            return attributeItem(i);
</del><ins>+    const Attribute* attributes =3D attributeBase();
+    for (unsigned i =3D 0, count =3D length(); i &lt; count; ++i) {
+        if (attributes[i].name().matches(name))
+            return &amp;attributes[i];
</ins><span class=3D"cx">     }
</span><span class=3D"cx">     return 0;
</span><span class=3D"cx"> }
</span><span class=3D"lines">@@ -999,9 +1008,7 @@
</span><span class=3D"cx"> inline const Attribute* ElementData::attribute=
Item(unsigned index) const
</span><span class=3D"cx"> {
</span><span class=3D"cx">     ASSERT_WITH_SECURITY_IMPLICATION(index &lt=
; length());
</span><del>-    if (m_isUnique)
-        return &amp;static_cast&lt;const UniqueElementData*&gt;(this)-&g=
t;m_attributeVector.at(index);
-    return &amp;static_cast&lt;const ShareableElementData*&gt;(this)-&gt=
;m_attributeArray[index];
</del><ins>+    return attributeBase() + index;
</ins><span class=3D"cx"> }
</span><span class=3D"cx">=20
</span><span class=3D"cx"> } // namespace
</span></span></pre>
</div>
</div>

</body>
</html>


More information about the webkit-changes mailing list