Commit 6943fd3b authored by benjamin@webkit.org's avatar benjamin@webkit.org

Add a balanced benchmark for QuerySelector

https://bugs.webkit.org/show_bug.cgi?id=116811

Reviewed by Sam Weinig.

The goal of this benchmark is to have an overview of querySelector as typically used
by webpages.

It uses queries similar to what is used by popular websites and applies somewhat
similar weighting for each type of query.

The tree used for the queries is intentionally kept simple to ensure we measure QuerySelector
a not purely the overhead of traversal.

* CSS/QuerySelector.html: Added.
* CSS/resources/query-selector.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@150781 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 38b8dd27
<!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
<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
2013-05-27 Benjamin Poulain <benjamin@webkit.org>
Add a balanced benchmark for QuerySelector
https://bugs.webkit.org/show_bug.cgi?id=116811
Reviewed by Sam Weinig.
The goal of this benchmark is to have an overview of querySelector as typically used
by webpages.
It uses queries similar to what is used by popular websites and applies somewhat
similar weighting for each type of query.
The tree used for the queries is intentionally kept simple to ensure we measure QuerySelector
a not purely the overhead of traversal.
* CSS/QuerySelector.html: Added.
* CSS/resources/query-selector.html: Added.
2013-05-18 Ryosuke Niwa <rniwa@webkit.org>
Add a performance test for copying
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment