⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 118736 in webkit


Ignore:
Timestamp:
May 29, 2012, 1:43:40 AM (14 years ago)
Author:
haraken@chromium.org
Message:

[Performance] Optimize querySelector() and querySelectorAll() by removing
redundant dummy style sheet creations
https://bugs.webkit.org/show_bug.cgi?id=87627

Reviewed by Antti Koivisto.

This patch improves performance of querySelector("#id") by 4.2% ~ 17.7%
in Safari and Chromium.

Performance tests: https://bugs.webkit.org/attachment.cgi?id=144288

The performance test results in my desktop:

[Safari/Mac]
document.querySelector("#headId") : 13.60 ms => 12.40 ms +9.68%
document.querySelector("#duplicatedId") : 14.80 ms => 14.20 ms +4.23%
document.querySelector("#tailId") : 13.80 ms => 12.20 ms +13.11%
document.querySelectorAll("#headId") : 17.80 ms => 14.60 ms +21.92%
document.querySelectorAll("#duplicatedId") : 513.80 ms => 471.60 ms +8.95%
document.querySelectorAll("#tailId") : 19.20 ms => 16.40 ms +17.07%
document.querySelector("h1") : 14.40 ms => 13.60 ms +5.88%
document.querySelector("h2") : 14.80 ms => 13.80 ms +7.25%
document.querySelector("h3") : 312.00 ms => 306.60 ms +1.76%
document.querySelectorAll("h1") : 322.00 ms => 314.60 ms +2.35%
document.querySelectorAll("h2") : 481.00 ms => 420.60 ms +14.36%
document.querySelectorAll("h3") : 326.80 ms => 315.80 ms +3.48%
document.querySelector(".headClass") : 16.20 ms => 15.40 ms +5.19%
document.querySelector(".duplicatedClass") : 17.00 ms => 15.40 ms +10.39%
document.querySelector(".tailClass") : 369.60 ms => 362.60 ms +1.93%
document.querySelectorAll(".headClass") : 388.20 ms => 377.60 ms +2.81%
document.querySelectorAll(".duplicatedClass") : 605.00 ms => 581.20 ms +4.09%
document.querySelectorAll(".tailClass") : 401.60 ms => 391.40 ms +2.61%

[Chromium/Linux]
ocument.querySelector("#headId") : 16.00 ms => 13.60 ms +17.65%
document.querySelector("#duplicatedId") : 16.80 ms => 15.40 ms +9.09%
document.querySelector("#tailId") : 16.00 ms => 13.60 ms +17.65%
document.querySelectorAll("#headId") : 29.00 ms => 25.00 ms +16.00%
document.querySelectorAll("#duplicatedId") : 561.40 ms => 505.20 ms +11.12%
document.querySelectorAll("#tailId") : 34.00 ms => 26.80 ms +26.87%
document.querySelector("h1") : 18.20 ms => 15.80 ms +15.19%
document.querySelector("h2") : 19.00 ms => 16.60 ms +14.46%
document.querySelector("h3") : 280.40 ms => 274.00 ms +2.34%
document.querySelectorAll("h1") : 300.20 ms => 365.20 ms -17.80%
document.querySelectorAll("h2") : 487.60 ms => 504.20 ms -3.29%
document.querySelectorAll("h3") : 349.40 ms => 324.00 ms +7.84%
document.querySelector(".headClass") : 18.40 ms => 16.00 ms +15.00%
document.querySelector(".duplicatedClass") : 19.40 ms => 16.20 ms +19.75%
document.querySelector(".tailClass") : 349.60 ms => 345.40 ms +1.22%
document.querySelectorAll(".headClass") : 382.80 ms => 378.20 ms +1.22%
document.querySelectorAll(".duplicatedClass") : 550.80 ms => 574.20 ms -4.08%
document.querySelectorAll(".tailClass") : 381.00 ms => 387.00 ms -1.55%

I've found that StyleSheetInternal::create() in CSSParser::parseSelector()
is a bottleneck of querySelector() and querySelectorAll().

void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorList)
{

RefPtr<StyleSheetInternal> dummyStyleSheet = StyleSheetInternal::create();
setStyleSheet(dummyStyleSheet.get());
...;

}

This patch removes a dummy style sheet. Previously the dummy style sheet
was needed to avoid null checks of m_styleSheet in CSSGrammer.y.
This patch fixes CSSGrammer.y so that it works fine with a null m_styleSheet.

Tests: fast/dom/SelectorAPI/*. No change in the test results.

  • css/CSSGrammar.y:
  • css/CSSParser.cpp:

(WebCore::CSSParser::parseSelector):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r118735 r118736  
     12012-05-29  Kentaro Hara  <haraken@chromium.org>
     2
     3        [Performance] Optimize querySelector() and querySelectorAll() by removing
     4        redundant dummy style sheet creations
     5        https://bugs.webkit.org/show_bug.cgi?id=87627
     6
     7        Reviewed by Antti Koivisto.
     8
     9        This patch improves performance of querySelector("#id") by 4.2% ~ 17.7%
     10        in Safari and Chromium.
     11
     12        Performance tests: https://bugs.webkit.org/attachment.cgi?id=144288
     13
     14        The performance test results in my desktop:
     15
     16        [Safari/Mac]
     17        document.querySelector("#headId") :               13.60 ms =>  12.40 ms  +9.68%
     18        document.querySelector("#duplicatedId") :         14.80 ms =>  14.20 ms  +4.23%
     19        document.querySelector("#tailId") :               13.80 ms =>  12.20 ms  +13.11%
     20        document.querySelectorAll("#headId") :            17.80 ms =>  14.60 ms  +21.92%
     21        document.querySelectorAll("#duplicatedId") :     513.80 ms => 471.60 ms  +8.95%
     22        document.querySelectorAll("#tailId") :            19.20 ms =>  16.40 ms  +17.07%
     23        document.querySelector("h1") :                    14.40 ms =>  13.60 ms  +5.88%
     24        document.querySelector("h2") :                    14.80 ms =>  13.80 ms  +7.25%
     25        document.querySelector("h3") :                   312.00 ms => 306.60 ms  +1.76%
     26        document.querySelectorAll("h1") :                322.00 ms => 314.60 ms  +2.35%
     27        document.querySelectorAll("h2") :                481.00 ms => 420.60 ms  +14.36%
     28        document.querySelectorAll("h3") :                326.80 ms => 315.80 ms  +3.48%
     29        document.querySelector(".headClass") :            16.20 ms =>  15.40 ms  +5.19%
     30        document.querySelector(".duplicatedClass") :      17.00 ms =>  15.40 ms  +10.39%
     31        document.querySelector(".tailClass") :           369.60 ms => 362.60 ms  +1.93%
     32        document.querySelectorAll(".headClass") :        388.20 ms => 377.60 ms  +2.81%
     33        document.querySelectorAll(".duplicatedClass") :  605.00 ms => 581.20 ms  +4.09%
     34        document.querySelectorAll(".tailClass") :        401.60 ms => 391.40 ms  +2.61%
     35
     36        [Chromium/Linux]
     37        ocument.querySelector("#headId") :                16.00 ms =>  13.60 ms  +17.65%
     38        document.querySelector("#duplicatedId") :         16.80 ms =>  15.40 ms  +9.09%
     39        document.querySelector("#tailId") :               16.00 ms =>  13.60 ms  +17.65%
     40        document.querySelectorAll("#headId") :            29.00 ms =>  25.00 ms  +16.00%
     41        document.querySelectorAll("#duplicatedId") :     561.40 ms => 505.20 ms  +11.12%
     42        document.querySelectorAll("#tailId") :            34.00 ms =>  26.80 ms  +26.87%
     43        document.querySelector("h1") :                    18.20 ms =>  15.80 ms  +15.19%
     44        document.querySelector("h2") :                    19.00 ms =>  16.60 ms  +14.46%
     45        document.querySelector("h3") :                   280.40 ms => 274.00 ms  +2.34%
     46        document.querySelectorAll("h1") :                300.20 ms => 365.20 ms  -17.80%
     47        document.querySelectorAll("h2") :                487.60 ms => 504.20 ms  -3.29%
     48        document.querySelectorAll("h3") :                349.40 ms => 324.00 ms  +7.84%
     49        document.querySelector(".headClass") :            18.40 ms =>  16.00 ms  +15.00%
     50        document.querySelector(".duplicatedClass") :      19.40 ms =>  16.20 ms  +19.75%
     51        document.querySelector(".tailClass") :           349.60 ms => 345.40 ms  +1.22%
     52        document.querySelectorAll(".headClass") :        382.80 ms => 378.20 ms  +1.22%
     53        document.querySelectorAll(".duplicatedClass") :  550.80 ms => 574.20 ms  -4.08%
     54        document.querySelectorAll(".tailClass") :        381.00 ms => 387.00 ms  -1.55%
     55
     56        I've found that StyleSheetInternal::create() in CSSParser::parseSelector()
     57        is a bottleneck of querySelector() and querySelectorAll().
     58
     59        void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorList)
     60        {
     61            RefPtr<StyleSheetInternal> dummyStyleSheet = StyleSheetInternal::create();
     62            setStyleSheet(dummyStyleSheet.get());
     63            ...;
     64        }
     65
     66        This patch removes a dummy style sheet. Previously the dummy style sheet
     67        was needed to avoid null checks of m_styleSheet in CSSGrammer.y.
     68        This patch fixes CSSGrammer.y so that it works fine with a null m_styleSheet.
     69
     70        Tests: fast/dom/SelectorAPI/*. No change in the test results.
     71
     72        * css/CSSGrammar.y:
     73        * css/CSSParser.cpp:
     74        (WebCore::CSSParser::parseSelector):
     75
    1762012-05-29  Nikolas Zimmermann  <nzimmermann@rim.com>
    277
  • trunk/Source/WebCore/css/CSSGrammar.y

    r118336 r118736  
    959959        $$ = p->createFloatingSelector();
    960960        if (p->m_styleSheet)
    961             $$->setTag(QualifiedName(namespacePrefix, $2,
    962                                       p->m_styleSheet->determineNamespace(namespacePrefix)));
    963         else // FIXME: Shouldn't this case be an error?
    964             $$->setTag(QualifiedName(nullAtom, $2, p->m_defaultNamespace));
     961            $$->setTag(QualifiedName(namespacePrefix, $2, p->m_styleSheet->determineNamespace(namespacePrefix)));
     962        else
     963            $$->setTag(QualifiedName(namespacePrefix, $2, p->m_defaultNamespace));
    965964    }
    966965    | namespace_selector element_name specifier_list {
     
    10911090        CSSParser* p = static_cast<CSSParser*>(parser);
    10921091        $$ = p->createFloatingSelector();
    1093         $$->setAttribute(QualifiedName(namespacePrefix, $4,
    1094                                    p->m_styleSheet->determineNamespace(namespacePrefix)));
     1092        if (p->m_styleSheet)
     1093            $$->setAttribute(QualifiedName(namespacePrefix, $4, p->m_styleSheet->determineNamespace(namespacePrefix)));
     1094        else
     1095            $$->setAttribute(QualifiedName(namespacePrefix, $4, p->m_defaultNamespace));
    10951096        $$->setMatch(CSSSelector::Set);
    10961097    }
     
    10991100        CSSParser* p = static_cast<CSSParser*>(parser);
    11001101        $$ = p->createFloatingSelector();
    1101         $$->setAttribute(QualifiedName(namespacePrefix, $4,
    1102                                    p->m_styleSheet->determineNamespace(namespacePrefix)));
     1102        if (p->m_styleSheet)
     1103            $$->setAttribute(QualifiedName(namespacePrefix, $4, p->m_styleSheet->determineNamespace(namespacePrefix)));
     1104        else
     1105            $$->setAttribute(QualifiedName(namespacePrefix, $4, p->m_defaultNamespace));
    11031106        $$->setMatch((CSSSelector::Match)$5);
    11041107        $$->setValue($7);
  • trunk/Source/WebCore/css/CSSParser.cpp

    r118712 r118736  
    11061106void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorList)
    11071107{
    1108     RefPtr<StyleSheetContents> dummyStyleSheet = StyleSheetContents::create();
    1109     setStyleSheet(dummyStyleSheet.get());
    11101108    m_selectorListForParseSelector = &selectorList;
    11111109
     
    11151113
    11161114    m_selectorListForParseSelector = 0;
    1117 
    1118     // The style sheet will be deleted right away, so it won't outlive the document.
    1119     ASSERT(dummyStyleSheet->hasOneRef());
    11201115}
    11211116
Note: See TracChangeset for help on using the changeset viewer.