--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Query selector benchmark.</title>
+ <script src="../resources/runner.js"></script>
+</head>
+<body>
+
+</body>
+<script>
+
+var iframe = document.createElement("iframe");
+iframe.style.display = "none";
+document.body.appendChild(iframe);
+
+function verifySizeExpectation(result, expectedSize)
+{
+ if (result.length != expectedSize)
+ throw "The query did not return the expected results."
+}
+
+var test = {
+ description: "This tests the performance of querySelector for a variety of common use cases.",
+ setup: function() {
+ // In order to restrict caching between operations, the tree is rebuilt from scratch.
+ var spec = PerfTestRunner.loadFile("resources/query-selector.html");
+ iframe.contentDocument.firstChild.innerHTML = spec;
+ },
+ run: function() {
+ var iFrameDocument = iframe.contentDocument;
+
+ for (var repeat = 0; repeat < 5; ++repeat) {
+ /// Various multiselector. About 15% of the queries.
+ for (var i = 0; i < 150; ++i) {
+ // Complex descent.
+ var result = iFrameDocument.querySelectorAll("html body div>#complex-multi-rules1 .some-class li[data-bar].some-class");
+ verifySizeExpectation(result, 1);
+
+ // id tag.
+ verifySizeExpectation(iFrameDocument.querySelectorAll("#complex-multi-rules2 acronym"), 1);
+ verifySizeExpectation(iFrameDocument.querySelectorAll("[id='complex-multi-rules2'] a"), 1);
+
+ // Multiple id + selector, sharing the same id.
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules3 source, #complex-multi-rules3 li, #complex-multi-rules3 td");
+ verifySizeExpectation(result, 11);
+ result = iFrameDocument.querySelectorAll("[id='complex-multi-rules3'] source, [id='complex-multi-rules3'] li, [id='complex-multi-rules3'] td");
+ verifySizeExpectation(result, 11);
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules3 .some-class, #complex-multi-rules3 .other-class");
+ verifySizeExpectation(result, 7);
+ result = iFrameDocument.querySelectorAll("[id='complex-multi-rules3'] .some-class, [id='complex-multi-rules3'] li, [id='complex-multi-rules3'] .other-class");
+ verifySizeExpectation(result, 7);
+
+ // Several Ids.
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules4 #complex-multi-rules4-sub1 #complex-multi-rules4-sub2 #complex-multi-rules4-sub3");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules4 [id='complex-multi-rules4-sub1'] #complex-multi-rules4-sub2 [id='complex-multi-rules4-sub3']");
+ result = iFrameDocument.querySelectorAll("[id='complex-multi-rules4'] [id='complex-multi-rules4-sub1'] [id='complex-multi-rules4-sub2'] [id='complex-multi-rules4-sub3']");
+ verifySizeExpectation(result, 1);
+
+ // Id sandwich: Multiple ids with selectors in between.
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules5 div #complex-multi-rules5-left ul li.other-class #complex-multi-rules5-right table tr>td");
+ verifySizeExpectation(result, 2);
+ result = iFrameDocument.querySelectorAll("div#complex-multi-rules5>div div#complex-multi-rules5-left ul .other-class p img#complex-multi-rules5-image");
+ verifySizeExpectation(result, 1);
+
+ // Named form attribute under hierarchy.
+ result = iFrameDocument.querySelectorAll("input[name='complex-multi-rules6-file-input']");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("form input[name='complex-multi-rules6-file-input']");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("form[name='complex-multi-rules6-form'] input[name='complex-multi-rules6-file-input']");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("form[name='complex-multi-rules6-form'] div input[name='complex-multi-rules6-file-input']");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("form[name='complex-multi-rules6-form'] div div input[name='complex-multi-rules6-file-input']");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("form[name='complex-multi-rules6-form']>div>div>input[name='complex-multi-rules6-file-input']");
+ verifySizeExpectation(result, 1);
+
+ // Hierarchy of tag and class.
+ result = iFrameDocument.querySelectorAll("div div a div div p.result-class");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("div div.some-class a.other-class div.another-class div p.result-class");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("div>div>a div div p.result-class");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("div>div.some-class>a.other-class>div.another-class>div>p.result-class");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("div div a div div p.result-class, div div.some-class a div div p.result-class, div div.some-class a.other-class div div p.result-class, div div.some-class a.other-class div.another-class div p.result-class");
+ verifySizeExpectation(result, 1);
+ }
+
+ // tag.class. About 10% of the queries
+ for (var i = 0; i < 100; ++i) {
+ result = iFrameDocument.querySelectorAll("details.details-class");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("summary.summary-class");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("article.article-class");
+ verifySizeExpectation(result, 1);
+ }
+
+ // Single selector query, 75% of the queries. Split between:
+ // -tag
+ // -[attribute]
+ // -exist
+ // -value=something
+ // -#id
+ // -.class
+ for (var i = 0; i < 750; ++i) {
+ // Tags.
+ result = iFrameDocument.querySelectorAll("details");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("summary");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("article");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("head");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("body");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("form");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("input");
+ verifySizeExpectation(result, 1);
+
+ // Attributes exists.
+ result = iFrameDocument.querySelectorAll("[data-foo]");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("[data-bar]");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("[title]");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("[href]");
+ verifySizeExpectation(result, 2);
+
+ // Attribute = value.
+ result = iFrameDocument.querySelectorAll("[data-foo=bar]");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("[data-bar=baz]");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("[title='WebKit Tempalte Framework']");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("[href='http://www.webkit.org/']");
+ verifySizeExpectation(result, 1);
+
+ // Id.
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules1");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules2");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules3");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules4");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules5");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules6");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules7");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll("#complex-multi-rules8");
+ verifySizeExpectation(result, 1);
+
+ // Id with duplicate.
+ result = iFrameDocument.querySelectorAll("#duplicate-id");
+ verifySizeExpectation(result, 3);
+
+ // .class.
+ result = iFrameDocument.querySelectorAll(".details-class");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll(".summary-class");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll(".article-class");
+ verifySizeExpectation(result, 1);
+ result = iFrameDocument.querySelectorAll(".result-class");
+ verifySizeExpectation(result, 1);
+ }
+ }
+ }
+}
+PerfTestRunner.measureTime(test);
+</script>
+</html>
\ No newline at end of file
--- /dev/null
+<html>
+<body>
+ <div>
+ <div id=complex-multi-rules1>
+ <p>Complex descent.</p>
+ <div class=some-class>
+ <ul>
+ <li data-foo="bar">one</li>
+ <li>two</li>
+ <li data-bar="baz" class=some-class>three</li>
+ </ul>
+ </div>
+ </div>
+
+ <div id=complex-multi-rules2>
+ <p>id + tag.</p>
+ <acronym title="WebKit Tempalte Framework">WTF</acronym>
+ <a href="http://www.apple.com">Link</a>
+ </div>
+
+ <div id=complex-multi-rules3>
+ <p>Multiple id + tag, sharing the same id.</p>
+ <audio>
+ <source class=some-class>
+ <source class=some-class>
+ <source class=some-class>
+ </audio>
+ <ol>
+ <li class=other-class>one</li>
+ <li class=other-class>two</li>
+ <li class=other-class>three</li>
+ <li class=other-class>four</li>
+ </ol>
+ <table>
+ <tr><td>cell</td><td>cell</td></tr>
+ <tr><td>cell</td><td>cell</td></tr>
+ </table>
+ </div>
+
+ <div id=complex-multi-rules4>
+ <p>Several Ids.</p>
+ Foo?
+ <div>
+ Bar?
+ <div id=complex-multi-rules4-sub1>
+ Foo?
+ <div>
+ Bar?
+ <div id=complex-multi-rules4-sub2>
+ Foo?
+ <div>
+ <div id=complex-multi-rules4-sub3>
+ Foo Bar!
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div id=complex-multi-rules5>
+ <p>Id sandwich: Multiple ids with selectors in between.</p>
+ <div>
+ Padding.
+ </div>
+ <div>
+ <div id=complex-multi-rules5-left>
+ <ul>
+ <li class=other-class>one</li>
+ <li class=other-class>two</li>
+ <li class=other-class>
+ three
+ <div id=complex-multi-rules5-right>
+ <p>complex-multi-rules5-right</p>
+ <table>
+ <tr><td>cell</td><td>cell</td></tr>
+ </table>
+ </div>
+ </li>
+ <li class=other-class>
+ four
+ <p>Some text. <img id=complex-multi-rules5-image></p>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div id=complex-multi-rules6>
+ <p>Named form attribute under hierarchy.</p>
+ <form name='complex-multi-rules6-form'>
+ <div>
+ <div>
+ <input type=file name=complex-multi-rules6-file-input>
+ </div>
+ </div>
+ </form>
+ </div>
+
+ <div id=complex-multi-rules7>
+ <p>Hierarchy of tag and class.</p>
+ <div class=some-class>
+ <a href="http://www.webkit.org/" class=other-class>
+ <div class=another-class>
+ <div>
+ <p class=result-class>FooBar!!!</p>
+ </div>
+ </div>
+ </a>
+ </div>
+ </div>
+
+ <div id=complex-multi-rules8>
+ <p>Commonly used restrictionselector.</p>
+ <div class=some-class>
+ <div class=some-class>
+ <ul>
+ <li>one</li>
+ <li>two</li>
+ <li>three</li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div id=tag-and-class>
+ <p>tag.class</p>
+ <details open class=details-class>
+ <summary class=summary-class>Summary</summary>
+ <p>Foo Bar!</p>
+ </details>
+ <article class=article-class>
+ <p>Lorem Ipsum</p>
+ </article>
+ </div>
+
+ <div id=duplicate-id>
+ </div>
+ <div id=duplicate-id>
+ </div>
+ <div id=duplicate-id>
+ </div>
+ </div>
+</body>
+</html>
\ No newline at end of file