haikuwebkit/PerformanceTests/testmem/tagcloud.js

272 lines
171 KiB
JavaScript
Raw Permalink Normal View History

Have a memory test where we can validate JSCs mini memory mode https://bugs.webkit.org/show_bug.cgi?id=185932 Reviewed by Mark Lam. PerformanceTests: We add a directory here with the contents of the testmem benchmark. To run it, use `Tools/Scripts/run-testmem`. To add new tests in the future, you just need to add JS files to this directory. * testmem: Added. * testmem/air.js: Added. * testmem/base64.js: Added. * testmem/basic.js: Added. * testmem/box2d.js: Added. * testmem/crypto-md5.js: Added. * testmem/date-format-tofte.js: Added. * testmem/earley-boyer.js: Added. * testmem/hash-map.js: Added. * testmem/regex-dna.js: Added. * testmem/splay.js: Added. * testmem/tagcloud.js: Added. Source/JavaScriptCore: This patch adds the testmem CLI. It takes as input a file to run and the number of iterations to run it (by default it runs it 20 times). Each iteration runs in a new JSContext. Each JSContext belongs to a VM that is created once. When finished, the CLI dumps out the peak memory usage of the process, the memory usage at the end of running all the iterations of the process, and the total time it took to run all the iterations. * JavaScriptCore.xcodeproj/project.pbxproj: * testmem: Added. * testmem/testmem.mm: Added. (description): (Footprint::now): (main): Tools: This patch adds the run-testmem script. This runs the new testmem CLI against the contents in the testmem benchmark. The contents of testmem contain tests from ARES-6, Sunspider, Octane, and JetStream. One iteration of the benchmark comprises of running each testmem test for a certain number of iterations. We collect the peak memory usage, the memory usage after running all the iterations, and the time it takes to run all the iterations. We then run the entire benchmark 3 times over. For each test, we compute the arithmetic mean over each iteration for time, peak memory, and end memory. The benchmark then computes a time score and memory score. peak memory score = geomean({peak memory of each individual test}) end memory score = geomean({end memory of each individual test}) memory score = geomean({peak memory score, end memory score}) time score = geomean({time score of each individual test}) We want the memory score to weigh improvements to peak memory usage and memory usage at the end equally. We plan to tune this benchmark in JSC's mini mode by improving the memory score while ensuring the time score is not more than 10-15% regressed. * Scripts/run-testmem: Added. Canonical link: https://commits.webkit.org/201421@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232193 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-05-25 19:05:25 +00:00
/*
* Copyright (C) 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Portions from:
json.js
2007-10-10
Public Domain
*/
// This test parses a JSON string giving tag names and popularity, and
// generates html markup for a "tagcloud" view.
if (!Object.prototype.toJSONString) {
Array.prototype.toJSONString = function (w) {
var a = [], // The array holding the partial texts.
i, // Loop counter.
l = this.length,
v; // The value to be stringified.
for (i = 0; i < l; i += 1) {
v = this[i];
switch (typeof v) {
case 'object':
if (v && typeof v.toJSONString === 'function') {
a.push(v.toJSONString(w));
} else {
a.push('null');
}
break;
case 'string':
case 'number':
case 'boolean':
a.push(v.toJSONString());
break;
default:
a.push('null');
}
}
return '[' + a.join(',') + ']';
};
Boolean.prototype.toJSONString = function () {
return String(this);
};
Date.prototype.toJSONString = function () {
function f(n) {
return n < 10 ? '0' + n : n;
}
return '"' + this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z"';
};
Number.prototype.toJSONString = function () {
return isFinite(this) ? String(this) : 'null';
};
Object.prototype.toJSONString = function (w) {
var a = [], // The array holding the partial texts.
k, // The current key.
i, // The loop counter.
v; // The current value.
if (w) {
for (i = 0; i < w.length; i += 1) {
k = w[i];
if (typeof k === 'string') {
v = this[k];
switch (typeof v) {
case 'object':
if (v) {
if (typeof v.toJSONString === 'function') {
a.push(k.toJSONString() + ':' +
v.toJSONString(w));
}
} else {
a.push(k.toJSONString() + ':null');
}
break;
case 'string':
case 'number':
case 'boolean':
a.push(k.toJSONString() + ':' + v.toJSONString());
}
}
}
} else {
for (k in this) {
if (typeof k === 'string' &&
Object.prototype.hasOwnProperty.apply(this, [k])) {
v = this[k];
switch (typeof v) {
case 'object':
if (v) {
if (typeof v.toJSONString === 'function') {
a.push(k.toJSONString() + ':' +
v.toJSONString());
}
} else {
a.push(k.toJSONString() + ':null');
}
break;
case 'string':
case 'number':
case 'boolean':
a.push(k.toJSONString() + ':' + v.toJSONString());
}
}
}
}
return '{' + a.join(',') + '}';
};
(function (s) {
var m = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
};
s.parseJSON = function (filter) {
var j;
function walk(k, v) {
var i, n;
if (v && typeof v === 'object') {
for (i in v) {
if (Object.prototype.hasOwnProperty.apply(v, [i])) {
n = walk(i, v[i]);
if (n !== undefined) {
v[i] = n;
}
}
}
}
return filter(k, v);
}
if (/^[\],:{}\s]*$/.test(this.replace(/\\./g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
j = eval('(' + this + ')');
return typeof filter === 'function' ? walk('', j) : j;
}
throw new SyntaxError('parseJSON');
};
s.toJSONString = function () {
if (/["\\\x00-\x1f]/.test(this)) {
return '"' + this.replace(/[\x00-\x1f\\"]/g, function (a) {
var c = m[a];
if (c) {
return c;
}
c = a.charCodeAt();
return '\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
}) + '"';
}
return '"' + this + '"';
};
})(String.prototype);
}
var tagInfoJSON = '[\n {\n \"tag\": "titillation",\n \"popularity\": 4294967296\n },\n {\n \"tag\": "foamless",\n \"popularity\": 1257718401\n },\n {\n \"tag\": "snarler",\n \"popularity\": 613166183\n },\n {\n \"tag\": "multangularness",\n \"popularity\": 368304452\n },\n {\n \"tag\": "Fesapo unventurous",\n \"popularity\": 248026512\n },\n {\n \"tag\": "esthesioblast",\n \"popularity\": 179556755\n },\n {\n \"tag\": "echeneidoid",\n \"popularity\": 136641578\n },\n {\n \"tag\": "embryoctony",\n \"popularity\": 107852576\n },\n {\n \"tag\": "undilatory",\n \"popularity\": 87537981\n },\n {\n \"tag\": "predisregard",\n \"popularity\": 72630939\n },\n {\n \"tag\": "allergenic",\n \"popularity\": 61345190\n },\n {\n \"tag\": "uncloudy",\n \"popularity\": 52580571\n },\n {\n \"tag\": "unforeseeably",\n \"popularity\": 45628109\n },\n {\n \"tag\": "sturniform",\n \"popularity\": 40013489\n },\n {\n \"tag\": "anesthetize",\n \"popularity\": 35409226\n },\n {\n \"tag\": "ametabolia",\n \"popularity\": 31583050\n },\n {\n \"tag\": "angiopathy",\n \"popularity\": 28366350\n },\n {\n \"tag\": "sultanaship",\n \"popularity\": 25634218\n },\n {\n \"tag\": "Frenchwise",\n \"popularity\": 23292461\n },\n {\n \"tag\": "cerviconasal",\n \"popularity\": 21268909\n },\n {\n \"tag\": "mercurialness",\n \"popularity\": 19507481\n },\n {\n \"tag\": "glutelin venditate",\n \"popularity\": 17964042\n },\n {\n \"tag\": "acred overblack",\n \"popularity\": 16603454\n },\n {\n \"tag\": "Atik",\n \"popularity\": 15397451\n },\n {\n \"tag\": "puncturer",\n \"popularity\": 14323077\n },\n {\n \"tag\": "pukatea",\n \"popularity\": 13361525\n },\n {\n \"tag\": "suberize",\n \"popularity\": 12497261\n },\n {\n \"tag\": "Godfrey",\n \"popularity\": 11717365\n },\n {\n \"tag\": "tetraptote",\n \"popularity\": 11011011\n },\n {\n \"tag\": "lucidness",\n \"popularity\": 10369074\n },\n {\n \"tag\": "tartness",\n \"popularity\": 9783815\n },\n {\n \"tag\": "axfetch",\n \"popularity\": 9248634\n },\n {\n \"tag\": "preacquittal",\n \"popularity\": 8757877\n },\n {\n \"tag\": "matris",\n \"popularity\": 8306671\n },\n {\n \"tag\": "hyphenate",\n \"popularity\": 7890801\n },\n {\n \"tag\": "semifabulous",\n \"popularity\": 7506606\n },\n {\n \"tag\": "oppressiveness",\n \"popularity\": 7150890\n },\n {\n \"tag\": "Protococcales",\n \"popularity\": 6820856\n },\n {\n \"tag\": "unpreventive",\n \"popularity\": 6514045\n },\n {\n \"tag\": "Cordia",\n \"popularity\": 6228289\n },\n {\n \"tag\": "Wakamba leaflike",\n \"popularity\": 5961668\n },\n {\n \"tag\": "dacryoma",\n \"popularity\": 5712480\n },\n {\n \"tag\": "inguinal",\n \"popularity\": 5479211\n },\n {\n \"tag\": "responseless",\n \"popularity\": 5260507\n },\n {\n \"tag\": "supplementarily",\n \"popularity\": 5055158\n },\n {\n \"tag\": "emu",\n \"popularity\": 4862079\n },\n {\n \"tag\": "countermeet",\n \"popularity\": 4680292\n },\n {\n \"tag\": "purrer",\n \"popularity\": 4508918\n },\n {\n \"tag\": "Corallinaceae",\n \"popularity\": 4347162\n },\n {\n \"tag\": "speculum",\n \"popularity\": 4194304\n },\n {\n \"tag\": "crimpness",\n \"popularity\": 4049690\n },\n {\n \"tag\": "antidetonant",\n \"popularity\": 3912727\n },\n {\n \"tag\": "topeewallah",\n \"popularity\": 3782875\n },\n {\n \"tag\": "fidalgo ballant",\n \"popularity\": 3659640\n },\n {\n \"tag\": "utriculose",\n \"popularity\": 3542572\n },\n {\n \"tag\": "testata",\n \"popularity\": 3431259\n },\n {\n \"tag\": "beltmaking",\n \"popularity\": 3325322\n },\n {\n \"tag\": "necrotype",\n \"popularity\": 3224413\n },\n {\n \"tag\": "ovistic",\n \"popularity\": 3128215\n },\n
var log2 = Math.log(2);
var tagInfo = tagInfoJSON.parseJSON(function(a, b) { if (a == "popularity") { return Math.log(b) / log2; } else {return b; } });
function makeTagCloud(tagInfo)
{
var output = '<div class="tagCloud" style="width: 100%">';
tagInfo.sort(function(a, b) { if (a.tag < b.tag) { return -1; } else if (a.tag == b.tag) { return 0; } else return 1; });
for (var i = 0; i < tagInfo.length; i++) {
var tag = tagInfo[i].tag;
var validates = true;
for (var j = 0; j < tag.length; j++) {
var ch = tag.charCodeAt(j);
if (ch < 0x20 || ch >= 0x7f) {
validates = false;
break;
}
}
if (!validates)
continue;
var url = "http://example.com/tag/" + tag.replace(" ", "").toLowerCase();
var popularity = tagInfo[i].popularity;
var color = 'rgb(' + Math.floor(255 * (popularity - 12) / 20) + ', 0, 255)';
output += ' <a href="' + url + '" style="font-size: ' + popularity + 'px; color: ' + color + '">' + tag + '</a> \n';
}
output += '</div>';
output.replace(" ", "&nbsp;");
return output;
}
var tagcloud = makeTagCloud(tagInfo);
var expectedMinLength = 315000;
if (tagcloud.length < expectedMinLength)
throw "ERROR: bad result: expected length at least " + expectedMinLength + " but got " + tagcloud.length;
tagInfo = null;