| // Copyright 2012 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS-IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| /** |
| * @fileoverview Performance test for goog.structs.Map and |
| * goog.labs.structs.Map. To run this test fairly, you would have to |
| * compile this via JsCompiler (with --export_test_functions), and |
| * pull the compiled JS into an empty HTML file. |
| * @author chrishenry@google.com (Chris Henry) |
| */ |
| |
| goog.provide('goog.labs.structs.MapPerf'); |
| goog.setTestOnly('goog.labs.structs.MapPerf'); |
| |
| goog.require('goog.asserts'); |
| goog.require('goog.dom'); |
| goog.require('goog.labs.structs.Map'); |
| goog.require('goog.structs.Map'); |
| goog.require('goog.testing.PerformanceTable'); |
| goog.require('goog.testing.jsunit'); |
| |
| goog.scope(function() { |
| var MapPerf = goog.labs.structs.MapPerf; |
| |
| |
| /** |
| * @typedef {goog.labs.structs.Map|goog.structs.Map} |
| */ |
| MapPerf.MapType; |
| |
| |
| /** |
| * @type {goog.testing.PerformanceTable} |
| */ |
| MapPerf.perfTable; |
| |
| |
| /** |
| * A key list. This maps loop index to key name to be used during |
| * benchmark. This ensure that we do not need to pay the cost of |
| * string concatenation/GC whenever we derive a key from loop index. |
| * |
| * This is filled once in setUpPage and then remain unchanged for the |
| * rest of the test case. |
| * |
| * @type {!Array<string>} |
| */ |
| MapPerf.keyList = []; |
| |
| |
| /** |
| * Maxium number of keys in keyList (and, by extension, the map under |
| * test). |
| * @type {number} |
| */ |
| MapPerf.MAX_NUM_KEY = 10000; |
| |
| |
| /** |
| * Fills the given map with generated key-value pair. |
| * @param {MapPerf.MapType} map The map to fill. |
| * @param {number} numKeys The number of key-value pair to fill. |
| */ |
| MapPerf.fillMap = function(map, numKeys) { |
| goog.asserts.assert(numKeys <= MapPerf.MAX_NUM_KEY); |
| |
| for (var i = 0; i < numKeys; ++i) { |
| map.set(MapPerf.keyList[i], i); |
| } |
| }; |
| |
| |
| /** |
| * Primes the given map with deletion of keys. |
| * @param {MapPerf.MapType} map The map to prime. |
| * @return {MapPerf.MapType} The primed map (for chaining). |
| */ |
| MapPerf.primeMapWithDeletion = function(map) { |
| for (var i = 0; i < 1000; ++i) { |
| map.set(MapPerf.keyList[i], i); |
| } |
| for (var i = 0; i < 1000; ++i) { |
| map.remove(MapPerf.keyList[i]); |
| } |
| return map; |
| }; |
| |
| |
| /** |
| * Runs performance test for Map#get with the given map. |
| * @param {MapPerf.MapType} map The map to stress. |
| * @param {string} message Message to be put in performance table. |
| */ |
| MapPerf.runPerformanceTestForMapGet = function(map, message) { |
| MapPerf.fillMap(map, 10000); |
| |
| MapPerf.perfTable.run( |
| function() { |
| // Creates local alias for map and keyList. |
| var localMap = map; |
| var localKeyList = MapPerf.keyList; |
| |
| for (var i = 0; i < 500; ++i) { |
| var sum = 0; |
| for (var j = 0; j < 10000; ++j) { |
| sum += localMap.get(localKeyList[j]); |
| } |
| } |
| }, |
| message); |
| }; |
| |
| |
| /** |
| * Runs performance test for Map#set with the given map. |
| * @param {MapPerf.MapType} map The map to stress. |
| * @param {string} message Message to be put in performance table. |
| */ |
| MapPerf.runPerformanceTestForMapSet = function(map, message) { |
| MapPerf.perfTable.run( |
| function() { |
| // Creates local alias for map and keyList. |
| var localMap = map; |
| var localKeyList = MapPerf.keyList; |
| |
| for (var i = 0; i < 500; ++i) { |
| for (var j = 0; j < 10000; ++j) { |
| localMap.set(localKeyList[i], i); |
| } |
| } |
| }, |
| message); |
| }; |
| |
| |
| goog.global['setUpPage'] = function() { |
| var content = goog.dom.createDom('div'); |
| goog.dom.insertChildAt(document.body, content, 0); |
| var ua = navigator.userAgent; |
| content.innerHTML = |
| '<h1>Closure Performance Tests - Map</h1>' + |
| '<p><strong>User-agent: </strong><span id="ua">' + ua + '</span></p>' + |
| '<div id="perf-table"></div>' + |
| '<hr>'; |
| |
| MapPerf.perfTable = new goog.testing.PerformanceTable( |
| goog.dom.getElement('perf-table')); |
| |
| // Fills keyList. |
| for (var i = 0; i < MapPerf.MAX_NUM_KEY; ++i) { |
| MapPerf.keyList.push('k' + i); |
| } |
| }; |
| |
| |
| goog.global['testGetFromLabsMap'] = function() { |
| MapPerf.runPerformanceTestForMapGet( |
| new goog.labs.structs.Map(), '#get: no previous deletion (Labs)'); |
| }; |
| |
| |
| goog.global['testGetFromOriginalMap'] = function() { |
| MapPerf.runPerformanceTestForMapGet( |
| new goog.structs.Map(), '#get: no previous deletion (Original)'); |
| }; |
| |
| |
| goog.global['testGetWithPreviousDeletionFromLabsMap'] = function() { |
| MapPerf.runPerformanceTestForMapGet( |
| MapPerf.primeMapWithDeletion(new goog.labs.structs.Map()), |
| '#get: with previous deletion (Labs)'); |
| }; |
| |
| |
| goog.global['testGetWithPreviousDeletionFromOriginalMap'] = function() { |
| MapPerf.runPerformanceTestForMapGet( |
| MapPerf.primeMapWithDeletion(new goog.structs.Map()), |
| '#get: with previous deletion (Original)'); |
| }; |
| |
| |
| goog.global['testSetFromLabsMap'] = function() { |
| MapPerf.runPerformanceTestForMapSet( |
| new goog.labs.structs.Map(), '#set: no previous deletion (Labs)'); |
| }; |
| |
| |
| goog.global['testSetFromOriginalMap'] = function() { |
| MapPerf.runPerformanceTestForMapSet( |
| new goog.structs.Map(), '#set: no previous deletion (Original)'); |
| }; |
| |
| }); // goog.scope |