3 /** Used to access the Firebug Lite panel (set by `run`). */
6 /** Used as a safe reference for `undefined` in pre ES5 environments. */
9 /** Used as a reference to the global object. */
10 var root = typeof global == 'object' && global || this;
12 /** Method and object shortcuts. */
13 var phantom = root.phantom,
14 amd = root.define && define.amd,
15 argv = root.process && process.argv,
16 document = !phantom && root.document,
18 params = root.arguments,
21 /** Add `console.log()` support for Rhino and RingoJS. */
22 var console = root.console || (root.console = { 'log': root.print });
24 /** The file path of the lodash file to test. */
25 var filePath = (function() {
30 result = params = phantom.args;
33 result = params = system.args;
36 result = params = argv;
40 var last = result[result.length - 1];
41 result = (result.length > min && !/perf(?:\.js)?$/.test(last)) ? last : '../lodash.js';
45 result = require('fs').realpathSync(result);
49 result = require.resolve(result);
55 /** Used to match path separators. */
56 var rePathSeparator = /[\/\\]/;
58 /** Used to detect primitive types. */
59 var rePrimitive = /^(?:boolean|number|string|undefined)$/;
61 /** Used to match RegExp special characters. */
62 var reSpecialChars = /[.*+?^=!:${}()|[\]\/\\]/g;
64 /** The `ui` object. */
65 var ui = root.ui || (root.ui = {
66 'buildPath': basename(filePath, '.js'),
67 'otherPath': 'underscore'
70 /** The lodash build basename. */
71 var buildName = root.buildName = basename(ui.buildPath, '.js');
73 /** The other library basename. */
74 var otherName = root.otherName = (function() {
75 var result = basename(ui.otherPath, '.js');
76 return result + (result == buildName ? ' (2)' : '');
79 /** Used to score performance. */
80 var score = { 'a': [], 'b': [] };
82 /** Used to queue benchmark suites. */
85 /** Used to resolve a value's internal [[Class]]. */
86 var toString = Object.prototype.toString;
88 /** Detect if in a browser environment. */
89 var isBrowser = isHostType(root, 'document') && isHostType(root, 'navigator');
91 /** Use a single "load" function. */
92 var load = (typeof require == 'function' && !amd)
97 var lodash = root.lodash || (root.lodash = (
98 lodash = load(filePath) || root._,
99 lodash = lodash._ || lodash,
100 (lodash.runInContext ? lodash.runInContext(root) : lodash),
104 /** Load Underscore. */
105 var _ = root.underscore || (root.underscore = (
106 _ = load('../vendor/underscore/underscore.js') || root._,
110 /** Load Benchmark.js. */
111 var Benchmark = root.Benchmark || (root.Benchmark = (
112 Benchmark = load('../node_modules/benchmark/benchmark.js') || root.Benchmark,
113 Benchmark = Benchmark.Benchmark || Benchmark,
114 Benchmark.runInContext(lodash.extend({}, root, { '_': lodash }))
117 /*--------------------------------------------------------------------------*/
120 * Gets the basename of the given `filePath`. If the file `extension` is passed,
121 * it will be removed from the basename.
124 * @param {string} path The file path to inspect.
125 * @param {string} extension The extension to remove.
126 * @returns {string} Returns the basename.
128 function basename(filePath, extension) {
129 var result = (filePath || '').split(rePathSeparator).pop();
130 return (arguments.length < 2)
132 : result.replace(RegExp(extension.replace(reSpecialChars, '\\$&') + '$'), '');
136 * Computes the geometric mean (log-average) of an array of values.
137 * See http://en.wikipedia.org/wiki/Geometric_mean#Relationship_with_arithmetic_mean_of_logarithms.
140 * @param {Array} array The array of values.
141 * @returns {number} The geometric mean.
143 function getGeometricMean(array) {
144 return Math.pow(Math.E, lodash.reduce(array, function(sum, x) {
145 return sum + Math.log(x);
146 }, 0) / array.length) || 0;
150 * Gets the Hz, i.e. operations per second, of `bench` adjusted for the
154 * @param {Object} bench The benchmark object.
155 * @returns {number} Returns the adjusted Hz.
157 function getHz(bench) {
158 var result = 1 / (bench.stats.mean + bench.stats.moe);
159 return isFinite(result) ? result : 0;
163 * Host objects can return type values that are different from their actual
164 * data type. The objects we are concerned with usually return non-primitive
165 * types of "object", "function", or "unknown".
168 * @param {*} object The owner of the property.
169 * @param {string} property The property to check.
170 * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`.
172 function isHostType(object, property) {
173 if (object == null) {
176 var type = typeof object[property];
177 return !rePrimitive.test(type) && (type != 'object' || !!object[property]);
181 * Logs text to the console.
184 * @param {string} text The text to log.
187 console.log(text + '');
189 // Scroll the Firebug Lite panel down.
190 fbPanel.scrollTop = fbPanel.scrollHeight;
195 * Runs all benchmark suites.
197 * @private (@public in the browser)
200 fbPanel = (fbPanel = root.document && document.getElementById('FirebugUI')) &&
201 (fbPanel = (fbPanel = fbPanel.contentWindow || fbPanel.contentDocument).document || fbPanel) &&
202 fbPanel.getElementById('fbPanel1');
204 log('\nSit back and relax, this may take a while.');
205 suites[0].run({ 'async': true });
208 /*--------------------------------------------------------------------------*/
210 lodash.extend(Benchmark.Suite.options, {
211 'onStart': function() {
212 log('\n' + this.name + ':');
214 'onCycle': function(event) {
217 'onComplete': function() {
218 for (var index = 0, length = this.length; index < length; index++) {
219 var bench = this[index];
225 log('There was a problem, skipping...');
228 var formatNumber = Benchmark.formatNumber,
229 fastest = this.filter('fastest'),
230 fastestHz = getHz(fastest[0]),
231 slowest = this.filter('slowest'),
232 slowestHz = getHz(slowest[0]),
233 aHz = getHz(this[0]),
234 bHz = getHz(this[1]);
236 if (fastest.length > 1) {
237 log('It\'s too close to call.');
238 aHz = bHz = slowestHz;
241 var percent = ((fastestHz / slowestHz) - 1) * 100;
244 fastest[0].name + ' is ' +
245 formatNumber(percent < 1 ? percent.toFixed(2) : Math.round(percent)) +
249 // Add score adjusted for margin of error.
253 // Remove current suite from queue.
258 suites[0].run({ 'async': true });
261 var aMeanHz = getGeometricMean(score.a),
262 bMeanHz = getGeometricMean(score.b),
263 fastestMeanHz = Math.max(aMeanHz, bMeanHz),
264 slowestMeanHz = Math.min(aMeanHz, bMeanHz),
265 xFaster = fastestMeanHz / slowestMeanHz,
266 percentFaster = formatNumber(Math.round((xFaster - 1) * 100)),
267 message = 'is ' + percentFaster + '% ' + (xFaster == 1 ? '' : '(' + formatNumber(xFaster.toFixed(2)) + 'x) ') + 'faster than';
270 if (aMeanHz >= bMeanHz) {
271 log('\n' + buildName + ' ' + message + ' ' + otherName + '.');
273 log('\n' + otherName + ' ' + message + ' ' + buildName + '.');
279 /*--------------------------------------------------------------------------*/
281 lodash.extend(Benchmark.options, {
284 var _ = global.underscore,\
285 lodash = global.lodash,\
286 belt = this.name == buildName ? lodash : _;\
288 var date = new Date,\
292 objects = Array(limit),\
293 numbers = Array(limit),\
294 fourNumbers = [5, 25, 10, 30],\
295 nestedNumbers = [1, [2], [3, [[4]]]],\
296 nestedObjects = [{}, [{}], [{}, [[{}]]]],\
297 twoNumbers = [12, 23];\
299 for (var index = 0; index < limit; index++) {\
300 numbers[index] = index;\
301 object["key" + index] = index;\
302 objects[index] = { "num": index };\
304 var strNumbers = numbers + "";\
306 if (typeof assign != "undefined") {\
307 var _assign = _.assign || _.extend,\
308 lodashAssign = lodash.assign;\
310 if (typeof bind != "undefined") {\
311 var thisArg = { "name": "fred" };\
313 var func = function(greeting, punctuation) {\
314 return (greeting || "hi") + " " + this.name + (punctuation || ".");\
317 var _boundNormal = _.bind(func, thisArg),\
318 _boundMultiple = _boundNormal,\
319 _boundPartial = _.bind(func, thisArg, "hi");\
321 var lodashBoundNormal = lodash.bind(func, thisArg),\
322 lodashBoundMultiple = lodashBoundNormal,\
323 lodashBoundPartial = lodash.bind(func, thisArg, "hi");\
325 for (index = 0; index < 10; index++) {\
326 _boundMultiple = _.bind(_boundMultiple, { "name": "fred" + index });\
327 lodashBoundMultiple = lodash.bind(lodashBoundMultiple, { "name": "fred" + index });\
330 if (typeof bindAll != "undefined") {\
331 var bindAllCount = -1,\
332 bindAllObjects = Array(this.count);\
334 var funcNames = belt.reject(belt.functions(belt).slice(0, 40), function(funcName) {\
335 return /^_/.test(funcName);\
338 // Potentially expensive.\n\
339 for (index = 0; index < this.count; index++) {\
340 bindAllObjects[index] = belt.reduce(funcNames, function(object, funcName) {\
341 object[funcName] = belt[funcName];\
346 if (typeof chaining != "undefined") {\
347 var even = function(v) { return v % 2 == 0; },\
348 square = function(v) { return v * v; };\
350 var largeArray = belt.range(10000),\
351 _chaining = _(largeArray).chain(),\
352 lodashChaining = lodash(largeArray).chain();\
354 if (typeof compact != "undefined") {\
355 var uncompacted = numbers.slice();\
356 uncompacted[2] = false;\
357 uncompacted[6] = null;\
358 uncompacted[18] = "";\
360 if (typeof flowRight != "undefined") {\
361 var compAddOne = function(n) { return n + 1; },\
362 compAddTwo = function(n) { return n + 2; },\
363 compAddThree = function(n) { return n + 3; };\
365 var _composed = _.flowRight && _.flowRight(compAddThree, compAddTwo, compAddOne),\
366 lodashComposed = lodash.flowRight && lodash.flowRight(compAddThree, compAddTwo, compAddOne);\
368 if (typeof countBy != "undefined" || typeof omit != "undefined") {\
369 var wordToNumber = {\
412 var words = belt.keys(wordToNumber).slice(0, limit);\
414 if (typeof flatten != "undefined") {\
415 var _flattenDeep = _.flatten([[1]])[0] !== 1,\
416 lodashFlattenDeep = lodash.flatten([[1]])[0] !== 1;\
418 if (typeof isEqual != "undefined") {\
419 var objectOfPrimitives = {\
425 var objectOfObjects = {\
426 "boolean": new Boolean(true),\
427 "number": new Number(1),\
428 "string": new String("a")\
431 var objectOfObjects2 = {\
432 "boolean": new Boolean(true),\
433 "number": new Number(1),\
434 "string": new String("A")\
439 objects2 = Array(limit),\
440 objects3 = Array(limit),\
441 numbers2 = Array(limit),\
442 numbers3 = Array(limit),\
443 nestedNumbers2 = [1, [2], [3, [[4]]]],\
444 nestedNumbers3 = [1, [2], [3, [[6]]]];\
446 for (index = 0; index < limit; index++) {\
447 object2["key" + index] = index;\
448 object3["key" + index] = index;\
449 objects2[index] = { "num": index };\
450 objects3[index] = { "num": index };\
451 numbers2[index] = index;\
452 numbers3[index] = index;\
454 object3["key" + (limit - 1)] = -1;\
455 objects3[limit - 1].num = -1;\
456 numbers3[limit - 1] = -1;\
458 if (typeof matches != "undefined") {\
459 var source = { "num": 9 };\
461 var _matcher = (_.matches || _.noop)(source),\
462 lodashMatcher = (lodash.matches || lodash.noop)(source);\
464 if (typeof multiArrays != "undefined") {\
465 var twentyValues = belt.shuffle(belt.range(20)),\
466 fortyValues = belt.shuffle(belt.range(40)),\
467 hundredSortedValues = belt.range(100),\
468 hundredValues = belt.shuffle(hundredSortedValues),\
469 hundredValues2 = belt.shuffle(hundredValues),\
470 hundredTwentyValues = belt.shuffle(belt.range(120)),\
471 hundredTwentyValues2 = belt.shuffle(hundredTwentyValues),\
472 twoHundredValues = belt.shuffle(belt.range(200)),\
473 twoHundredValues2 = belt.shuffle(twoHundredValues);\
475 if (typeof partial != "undefined") {\
476 var func = function(greeting, punctuation) {\
477 return greeting + " fred" + (punctuation || ".");\
480 var _partial = _.partial(func, "hi"),\
481 lodashPartial = lodash.partial(func, "hi");\
483 if (typeof template != "undefined") {\
485 "header1": "Header1",\
486 "header2": "Header2",\
487 "header3": "Header3",\
488 "header4": "Header4",\
489 "header5": "Header5",\
490 "header6": "Header6",\
491 "list": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]\
496 "<h1 class=\'header1\'><%= header1 %></h1>" +\
497 "<h2 class=\'header2\'><%= header2 %></h2>" +\
498 "<h3 class=\'header3\'><%= header3 %></h3>" +\
499 "<h4 class=\'header4\'><%= header4 %></h4>" +\
500 "<h5 class=\'header5\'><%= header5 %></h5>" +\
501 "<h6 class=\'header6\'><%= header6 %></h6>" +\
502 "<ul class=\'list\'>" +\
503 "<% for (var index = 0, length = list.length; index < length; index++) { %>" +\
504 "<li class=\'item\'><%= list[index] %></li>" +\
511 "<h1 class=\'header1\'><%= data.header1 %></h1>" +\
512 "<h2 class=\'header2\'><%= data.header2 %></h2>" +\
513 "<h3 class=\'header3\'><%= data.header3 %></h3>" +\
514 "<h4 class=\'header4\'><%= data.header4 %></h4>" +\
515 "<h5 class=\'header5\'><%= data.header5 %></h5>" +\
516 "<h6 class=\'header6\'><%= data.header6 %></h6>" +\
517 "<ul class=\'list\'>" +\
518 "<% for (var index = 0, length = data.list.length; index < length; index++) { %>" +\
519 "<li class=\'item\'><%= data.list[index] %></li>" +\
524 var settingsObject = { "variable": "data" };\
526 var _tpl = _.template(tpl),\
527 _tplVerbose = _.template(tplVerbose, null, settingsObject);\
529 var lodashTpl = lodash.template(tpl),\
530 lodashTplVerbose = lodash.template(tplVerbose, null, settingsObject);\
532 if (typeof wrap != "undefined") {\
533 var add = function(a, b) {\
537 var average = function(func, a, b) {\
538 return (func(a, b) / 2).toFixed(2);\
541 var _wrapped = _.wrap(add, average);\
542 lodashWrapped = lodash.wrap(add, average);\
544 if (typeof zip != "undefined") {\
545 var unzipped = [["a", "b", "c"], [1, 2, 3], [true, false, true]];\
549 /*--------------------------------------------------------------------------*/
552 Benchmark.Suite('`_(...).map(...).filter(...).take(...).value()`')
554 'fn': 'lodashChaining.map(square).filter(even).take(100).value()',
555 'teardown': 'function chaining(){}'
558 'fn': '_chaining.map(square).filter(even).take(100).value()',
559 'teardown': 'function chaining(){}'
563 /*--------------------------------------------------------------------------*/
566 Benchmark.Suite('`_.assign`')
568 'fn': 'lodashAssign({}, object)',
569 'teardown': 'function assign(){}'
572 'fn': '_assign({}, object)',
573 'teardown': 'function assign(){}'
578 Benchmark.Suite('`_.assign` with multiple sources')
580 'fn': 'lodashAssign({}, object, object)',
581 'teardown': 'function assign(){}'
584 'fn': '_assign({}, object, object)',
585 'teardown': 'function assign(){}'
589 /*--------------------------------------------------------------------------*/
592 Benchmark.Suite('`_.bind` (slow path)')
594 'fn': 'lodash.bind(function() { return this.name; }, { "name": "fred" })',
595 'teardown': 'function bind(){}'
598 'fn': '_.bind(function() { return this.name; }, { "name": "fred" })',
599 'teardown': 'function bind(){}'
604 Benchmark.Suite('bound call with arguments')
606 'fn': 'lodashBoundNormal("hi", "!")',
607 'teardown': 'function bind(){}'
610 'fn': '_boundNormal("hi", "!")',
611 'teardown': 'function bind(){}'
616 Benchmark.Suite('bound and partially applied call with arguments')
618 'fn': 'lodashBoundPartial("!")',
619 'teardown': 'function bind(){}'
622 'fn': '_boundPartial("!")',
623 'teardown': 'function bind(){}'
628 Benchmark.Suite('bound multiple times')
630 'fn': 'lodashBoundMultiple()',
631 'teardown': 'function bind(){}'
634 'fn': '_boundMultiple()',
635 'teardown': 'function bind(){}'
639 /*--------------------------------------------------------------------------*/
642 Benchmark.Suite('`_.bindAll`')
644 'fn': 'lodash.bindAll(bindAllObjects[++bindAllCount], funcNames)',
645 'teardown': 'function bindAll(){}'
648 'fn': '_.bindAll(bindAllObjects[++bindAllCount], funcNames)',
649 'teardown': 'function bindAll(){}'
653 /*--------------------------------------------------------------------------*/
656 Benchmark.Suite('`_.clone` with an array')
658 lodash.clone(numbers)'
666 Benchmark.Suite('`_.clone` with an object')
668 lodash.clone(object)'
675 /*--------------------------------------------------------------------------*/
678 Benchmark.Suite('`_.compact`')
680 'fn': 'lodash.compact(uncompacted)',
681 'teardown': 'function compact(){}'
684 'fn': '_.compact(uncompacted)',
685 'teardown': 'function compact(){}'
689 /*--------------------------------------------------------------------------*/
692 Benchmark.Suite('`_.countBy` with `callback` iterating an array')
694 lodash.countBy(numbers, function(num) { return num >> 1; })'
697 _.countBy(numbers, function(num) { return num >> 1; })'
702 Benchmark.Suite('`_.countBy` with `property` name iterating an array')
704 'fn': 'lodash.countBy(words, "length")',
705 'teardown': 'function countBy(){}'
708 'fn': '_.countBy(words, "length")',
709 'teardown': 'function countBy(){}'
714 Benchmark.Suite('`_.countBy` with `callback` iterating an object')
716 'fn': 'lodash.countBy(wordToNumber, function(num) { return num >> 1; })',
717 'teardown': 'function countBy(){}'
720 'fn': '_.countBy(wordToNumber, function(num) { return num >> 1; })',
721 'teardown': 'function countBy(){}'
725 /*--------------------------------------------------------------------------*/
728 Benchmark.Suite('`_.defaults`')
730 lodash.defaults({ "key2": 2, "key6": 6, "key18": 18 }, object)'
733 _.defaults({ "key2": 2, "key6": 6, "key18": 18 }, object)'
737 /*--------------------------------------------------------------------------*/
740 Benchmark.Suite('`_.difference`')
742 lodash.difference(numbers, twoNumbers, fourNumbers)'
745 _.difference(numbers, twoNumbers, fourNumbers)'
750 Benchmark.Suite('`_.difference` iterating 20 and 40 elements')
752 'fn': 'lodash.difference(twentyValues, fortyValues)',
753 'teardown': 'function multiArrays(){}'
756 'fn': '_.difference(twentyValues, fortyValues)',
757 'teardown': 'function multiArrays(){}'
762 Benchmark.Suite('`_.difference` iterating 200 elements')
764 'fn': 'lodash.difference(twoHundredValues, twoHundredValues2)',
765 'teardown': 'function multiArrays(){}'
768 'fn': '_.difference(twoHundredValues, twoHundredValues2)',
769 'teardown': 'function multiArrays(){}'
773 /*--------------------------------------------------------------------------*/
776 Benchmark.Suite('`_.each` iterating an array')
779 lodash.each(numbers, function(num) {\
780 result.push(num * 2);\
785 _.each(numbers, function(num) {\
786 result.push(num * 2);\
792 Benchmark.Suite('`_.each` iterating an object')
795 lodash.each(object, function(num) {\
796 result.push(num * 2);\
801 _.each(object, function(num) {\
802 result.push(num * 2);\
807 /*--------------------------------------------------------------------------*/
810 Benchmark.Suite('`_.every` iterating an array')
812 lodash.every(numbers, function(num) {\
817 _.every(numbers, function(num) {\
824 Benchmark.Suite('`_.every` iterating an object')
826 lodash.every(object, function(num) {\
831 _.every(object, function(num) {\
837 /*--------------------------------------------------------------------------*/
840 Benchmark.Suite('`_.filter` iterating an array')
842 lodash.filter(numbers, function(num) {\
847 _.filter(numbers, function(num) {\
854 Benchmark.Suite('`_.filter` iterating an object')
856 lodash.filter(object, function(num) {\
861 _.filter(object, function(num) {\
868 Benchmark.Suite('`_.filter` with `_.matches` shorthand')
870 'fn': 'lodash.filter(objects, source)',
871 'teardown': 'function matches(){}'
874 'fn': '_.filter(objects, source)',
875 'teardown': 'function matches(){}'
880 Benchmark.Suite('`_.filter` with `_.matches` predicate')
882 'fn': 'lodash.filter(objects, lodashMatcher)',
883 'teardown': 'function matches(){}'
886 'fn': '_.filter(objects, _matcher)',
887 'teardown': 'function matches(){}'
891 /*--------------------------------------------------------------------------*/
894 Benchmark.Suite('`_.find` iterating an array')
896 lodash.find(numbers, function(num) {\
897 return num === (limit - 1);\
901 _.find(numbers, function(num) {\
902 return num === (limit - 1);\
908 Benchmark.Suite('`_.find` iterating an object')
910 lodash.find(object, function(value, key) {\
911 return /\D9$/.test(key);\
915 _.find(object, function(value, key) {\
916 return /\D9$/.test(key);\
921 // Avoid Underscore induced `OutOfMemoryError` in Rhino and Ringo.
923 Benchmark.Suite('`_.find` with `_.matches` shorthand')
925 'fn': 'lodash.find(objects, source)',
926 'teardown': 'function matches(){}'
929 'fn': '_.find(objects, source)',
930 'teardown': 'function matches(){}'
934 /*--------------------------------------------------------------------------*/
937 Benchmark.Suite('`_.flatten`')
939 'fn': 'lodash.flatten(nestedNumbers, !lodashFlattenDeep)',
940 'teardown': 'function flatten(){}'
943 'fn': '_.flatten(nestedNumbers, !_flattenDeep)',
944 'teardown': 'function flatten(){}'
948 /*--------------------------------------------------------------------------*/
951 Benchmark.Suite('`_.flattenDeep` nested arrays of numbers')
953 'fn': 'lodash.flattenDeep(nestedNumbers)',
954 'teardown': 'function flatten(){}'
957 'fn': '_.flattenDeep(nestedNumbers)',
958 'teardown': 'function flatten(){}'
963 Benchmark.Suite('`_.flattenDeep` nest arrays of objects')
965 'fn': 'lodash.flattenDeep(nestedObjects)',
966 'teardown': 'function flatten(){}'
969 'fn': '_.flattenDeep(nestedObjects)',
970 'teardown': 'function flatten(){}'
974 /*--------------------------------------------------------------------------*/
977 Benchmark.Suite('`_.flowRight`')
979 'fn': 'lodash.flowRight(compAddThree, compAddTwo, compAddOne)',
980 'teardown': 'function flowRight(){}'
983 'fn': '_.flowRight(compAddThree, compAddTwo, compAddOne)',
984 'teardown': 'function flowRight(){}'
989 Benchmark.Suite('composed call')
991 'fn': 'lodashComposed(0)',
992 'teardown': 'function flowRight(){}'
995 'fn': '_composed(0)',
996 'teardown': 'function flowRight(){}'
1000 /*--------------------------------------------------------------------------*/
1003 Benchmark.Suite('`_.functions`')
1005 lodash.functions(lodash)'
1008 _.functions(lodash)'
1012 /*--------------------------------------------------------------------------*/
1015 Benchmark.Suite('`_.groupBy` with `callback` iterating an array')
1017 lodash.groupBy(numbers, function(num) { return num >> 1; })'
1020 _.groupBy(numbers, function(num) { return num >> 1; })'
1025 Benchmark.Suite('`_.groupBy` with `property` name iterating an array')
1027 'fn': 'lodash.groupBy(words, "length")',
1028 'teardown': 'function countBy(){}'
1031 'fn': '_.groupBy(words, "length")',
1032 'teardown': 'function countBy(){}'
1037 Benchmark.Suite('`_.groupBy` with `callback` iterating an object')
1039 'fn': 'lodash.groupBy(wordToNumber, function(num) { return num >> 1; })',
1040 'teardown': 'function countBy(){}'
1043 'fn': '_.groupBy(wordToNumber, function(num) { return num >> 1; })',
1044 'teardown': 'function countBy(){}'
1048 /*--------------------------------------------------------------------------*/
1051 Benchmark.Suite('`_.includes` searching an array')
1053 lodash.includes(numbers, limit - 1)'
1056 _.includes(numbers, limit - 1)'
1061 Benchmark.Suite('`_.includes` searching an object')
1063 lodash.includes(object, limit - 1)'
1066 _.includes(object, limit - 1)'
1070 if (lodash.includes('ab', 'ab') && _.includes('ab', 'ab')) {
1072 Benchmark.Suite('`_.includes` searching a string')
1074 lodash.includes(strNumbers, "," + (limit - 1))'
1077 _.includes(strNumbers, "," + (limit - 1))'
1082 /*--------------------------------------------------------------------------*/
1085 Benchmark.Suite('`_.indexOf`')
1087 'fn': 'lodash.indexOf(hundredSortedValues, 99)',
1088 'teardown': 'function multiArrays(){}'
1091 'fn': '_.indexOf(hundredSortedValues, 99)',
1092 'teardown': 'function multiArrays(){}'
1096 /*--------------------------------------------------------------------------*/
1099 Benchmark.Suite('`_.intersection`')
1101 lodash.intersection(numbers, twoNumbers, fourNumbers)'
1104 _.intersection(numbers, twoNumbers, fourNumbers)'
1109 Benchmark.Suite('`_.intersection` iterating 120 elements')
1111 'fn': 'lodash.intersection(hundredTwentyValues, hundredTwentyValues2)',
1112 'teardown': 'function multiArrays(){}'
1115 'fn': '_.intersection(hundredTwentyValues, hundredTwentyValues2)',
1116 'teardown': 'function multiArrays(){}'
1120 /*--------------------------------------------------------------------------*/
1123 Benchmark.Suite('`_.invert`')
1125 lodash.invert(object)'
1132 /*--------------------------------------------------------------------------*/
1135 Benchmark.Suite('`_.invokeMap` iterating an array')
1137 lodash.invokeMap(numbers, "toFixed")'
1140 _.invokeMap(numbers, "toFixed")'
1145 Benchmark.Suite('`_.invokeMap` with arguments iterating an array')
1147 lodash.invokeMap(numbers, "toFixed", 1)'
1150 _.invokeMap(numbers, "toFixed", 1)'
1155 Benchmark.Suite('`_.invokeMap` with a function for `path` iterating an array')
1157 lodash.invokeMap(numbers, Number.prototype.toFixed, 1)'
1160 _.invokeMap(numbers, Number.prototype.toFixed, 1)'
1165 Benchmark.Suite('`_.invokeMap` iterating an object')
1167 lodash.invokeMap(object, "toFixed", 1)'
1170 _.invokeMap(object, "toFixed", 1)'
1174 /*--------------------------------------------------------------------------*/
1177 Benchmark.Suite('`_.isEqual` comparing primitives')
1180 lodash.isEqual(1, "1");\
1181 lodash.isEqual(1, 1)',
1182 'teardown': 'function isEqual(){}'
1188 'teardown': 'function isEqual(){}'
1193 Benchmark.Suite('`_.isEqual` comparing primitives and their object counterparts (edge case)')
1196 lodash.isEqual(objectOfPrimitives, objectOfObjects);\
1197 lodash.isEqual(objectOfPrimitives, objectOfObjects2)',
1198 'teardown': 'function isEqual(){}'
1202 _.isEqual(objectOfPrimitives, objectOfObjects);\
1203 _.isEqual(objectOfPrimitives, objectOfObjects2)',
1204 'teardown': 'function isEqual(){}'
1209 Benchmark.Suite('`_.isEqual` comparing arrays')
1212 lodash.isEqual(numbers, numbers2);\
1213 lodash.isEqual(numbers2, numbers3)',
1214 'teardown': 'function isEqual(){}'
1218 _.isEqual(numbers, numbers2);\
1219 _.isEqual(numbers2, numbers3)',
1220 'teardown': 'function isEqual(){}'
1225 Benchmark.Suite('`_.isEqual` comparing nested arrays')
1228 lodash.isEqual(nestedNumbers, nestedNumbers2);\
1229 lodash.isEqual(nestedNumbers2, nestedNumbers3)',
1230 'teardown': 'function isEqual(){}'
1234 _.isEqual(nestedNumbers, nestedNumbers2);\
1235 _.isEqual(nestedNumbers2, nestedNumbers3)',
1236 'teardown': 'function isEqual(){}'
1241 Benchmark.Suite('`_.isEqual` comparing arrays of objects')
1244 lodash.isEqual(objects, objects2);\
1245 lodash.isEqual(objects2, objects3)',
1246 'teardown': 'function isEqual(){}'
1250 _.isEqual(objects, objects2);\
1251 _.isEqual(objects2, objects3)',
1252 'teardown': 'function isEqual(){}'
1257 Benchmark.Suite('`_.isEqual` comparing objects')
1260 lodash.isEqual(object, object2);\
1261 lodash.isEqual(object2, object3)',
1262 'teardown': 'function isEqual(){}'
1266 _.isEqual(object, object2);\
1267 _.isEqual(object2, object3)',
1268 'teardown': 'function isEqual(){}'
1272 /*--------------------------------------------------------------------------*/
1275 Benchmark.Suite('`_.isArguments`, `_.isDate`, `_.isFunction`, `_.isNumber`, `_.isObject`, `_.isRegExp`')
1277 lodash.isArguments(arguments);\
1278 lodash.isArguments(object);\
1279 lodash.isDate(date);\
1280 lodash.isDate(object);\
1281 lodash.isFunction(lodash);\
1282 lodash.isFunction(object);\
1283 lodash.isNumber(1);\
1284 lodash.isNumber(object);\
1285 lodash.isObject(object);\
1286 lodash.isObject(1);\
1287 lodash.isRegExp(regexp);\
1288 lodash.isRegExp(object)'
1291 _.isArguments(arguments);\
1292 _.isArguments(object);\
1296 _.isFunction(object);\
1298 _.isNumber(object);\
1299 _.isObject(object);\
1301 _.isRegExp(regexp);\
1306 /*--------------------------------------------------------------------------*/
1309 Benchmark.Suite('`_.keys` (uses native `Object.keys` if available)')
1311 lodash.keys(object)'
1318 /*--------------------------------------------------------------------------*/
1321 Benchmark.Suite('`_.lastIndexOf`')
1323 'fn': 'lodash.lastIndexOf(hundredSortedValues, 0)',
1324 'teardown': 'function multiArrays(){}'
1327 'fn': '_.lastIndexOf(hundredSortedValues, 0)',
1328 'teardown': 'function multiArrays(){}'
1332 /*--------------------------------------------------------------------------*/
1335 Benchmark.Suite('`_.map` iterating an array')
1337 lodash.map(objects, function(value) {\
1342 _.map(objects, function(value) {\
1349 Benchmark.Suite('`_.map` iterating an object')
1351 lodash.map(object, function(value) {\
1356 _.map(object, function(value) {\
1363 Benchmark.Suite('`_.map` with `_.property` shorthand')
1365 lodash.map(objects, "num")'
1368 _.map(objects, "num")'
1372 /*--------------------------------------------------------------------------*/
1375 Benchmark.Suite('`_.max`')
1377 lodash.max(numbers)'
1384 /*--------------------------------------------------------------------------*/
1387 Benchmark.Suite('`_.min`')
1389 lodash.min(numbers)'
1396 /*--------------------------------------------------------------------------*/
1399 Benchmark.Suite('`_.omit` iterating 20 properties, omitting 2 keys')
1401 lodash.omit(object, "key6", "key13")'
1404 _.omit(object, "key6", "key13")'
1409 Benchmark.Suite('`_.omit` iterating 40 properties, omitting 20 keys')
1411 'fn': 'lodash.omit(wordToNumber, words)',
1412 'teardown': 'function omit(){}'
1415 'fn': '_.omit(wordToNumber, words)',
1416 'teardown': 'function omit(){}'
1420 /*--------------------------------------------------------------------------*/
1423 Benchmark.Suite('`_.partial` (slow path)')
1425 'fn': 'lodash.partial(function(greeting) { return greeting + " " + this.name; }, "hi")',
1426 'teardown': 'function partial(){}'
1429 'fn': '_.partial(function(greeting) { return greeting + " " + this.name; }, "hi")',
1430 'teardown': 'function partial(){}'
1435 Benchmark.Suite('partially applied call with arguments')
1437 'fn': 'lodashPartial("!")',
1438 'teardown': 'function partial(){}'
1441 'fn': '_partial("!")',
1442 'teardown': 'function partial(){}'
1446 /*--------------------------------------------------------------------------*/
1449 Benchmark.Suite('`_.partition` iterating an array')
1451 lodash.partition(numbers, function(num) {\
1456 _.partition(numbers, function(num) {\
1463 Benchmark.Suite('`_.partition` iterating an object')
1465 lodash.partition(object, function(num) {\
1470 _.partition(object, function(num) {\
1476 /*--------------------------------------------------------------------------*/
1479 Benchmark.Suite('`_.pick`')
1481 lodash.pick(object, "key6", "key13")'
1484 _.pick(object, "key6", "key13")'
1488 /*--------------------------------------------------------------------------*/
1491 Benchmark.Suite('`_.reduce` iterating an array')
1493 lodash.reduce(numbers, function(result, value, index) {\
1494 result[index] = value;\
1499 _.reduce(numbers, function(result, value, index) {\
1500 result[index] = value;\
1507 Benchmark.Suite('`_.reduce` iterating an object')
1509 lodash.reduce(object, function(result, value, key) {\
1510 result.push(key, value);\
1515 _.reduce(object, function(result, value, key) {\
1516 result.push(key, value);\
1522 /*--------------------------------------------------------------------------*/
1525 Benchmark.Suite('`_.reduceRight` iterating an array')
1527 lodash.reduceRight(numbers, function(result, value, index) {\
1528 result[index] = value;\
1533 _.reduceRight(numbers, function(result, value, index) {\
1534 result[index] = value;\
1541 Benchmark.Suite('`_.reduceRight` iterating an object')
1543 lodash.reduceRight(object, function(result, value, key) {\
1544 result.push(key, value);\
1549 _.reduceRight(object, function(result, value, key) {\
1550 result.push(key, value);\
1556 /*--------------------------------------------------------------------------*/
1559 Benchmark.Suite('`_.reject` iterating an array')
1561 lodash.reject(numbers, function(num) {\
1566 _.reject(numbers, function(num) {\
1573 Benchmark.Suite('`_.reject` iterating an object')
1575 lodash.reject(object, function(num) {\
1580 _.reject(object, function(num) {\
1586 /*--------------------------------------------------------------------------*/
1589 Benchmark.Suite('`_.sampleSize`')
1591 lodash.sampleSize(numbers, limit / 2)'
1594 _.sampleSize(numbers, limit / 2)'
1598 /*--------------------------------------------------------------------------*/
1601 Benchmark.Suite('`_.shuffle`')
1603 lodash.shuffle(numbers)'
1610 /*--------------------------------------------------------------------------*/
1613 Benchmark.Suite('`_.size` with an object')
1615 lodash.size(object)'
1622 /*--------------------------------------------------------------------------*/
1625 Benchmark.Suite('`_.some` iterating an array')
1627 lodash.some(numbers, function(num) {\
1628 return num == (limit - 1);\
1632 _.some(numbers, function(num) {\
1633 return num == (limit - 1);\
1639 Benchmark.Suite('`_.some` iterating an object')
1641 lodash.some(object, function(num) {\
1642 return num == (limit - 1);\
1646 _.some(object, function(num) {\
1647 return num == (limit - 1);\
1652 /*--------------------------------------------------------------------------*/
1655 Benchmark.Suite('`_.sortBy` with `callback`')
1657 lodash.sortBy(numbers, function(num) { return Math.sin(num); })'
1660 _.sortBy(numbers, function(num) { return Math.sin(num); })'
1665 Benchmark.Suite('`_.sortBy` with `property` name')
1667 'fn': 'lodash.sortBy(words, "length")',
1668 'teardown': 'function countBy(){}'
1671 'fn': '_.sortBy(words, "length")',
1672 'teardown': 'function countBy(){}'
1676 /*--------------------------------------------------------------------------*/
1679 Benchmark.Suite('`_.sortedIndex`')
1681 lodash.sortedIndex(numbers, limit)'
1684 _.sortedIndex(numbers, limit)'
1688 /*--------------------------------------------------------------------------*/
1691 Benchmark.Suite('`_.sortedIndexBy`')
1694 lodash.sortedIndexBy(words, "twenty-five", function(value) {\
1695 return wordToNumber[value];\
1697 'teardown': 'function countBy(){}'
1701 _.sortedIndexBy(words, "twenty-five", function(value) {\
1702 return wordToNumber[value];\
1704 'teardown': 'function countBy(){}'
1708 /*--------------------------------------------------------------------------*/
1711 Benchmark.Suite('`_.sortedIndexOf`')
1713 'fn': 'lodash.sortedIndexOf(hundredSortedValues, 99)',
1714 'teardown': 'function multiArrays(){}'
1717 'fn': '_.sortedIndexOf(hundredSortedValues, 99)',
1718 'teardown': 'function multiArrays(){}'
1722 /*--------------------------------------------------------------------------*/
1725 Benchmark.Suite('`_.sortedLastIndexOf`')
1727 'fn': 'lodash.sortedLastIndexOf(hundredSortedValues, 0)',
1728 'teardown': 'function multiArrays(){}'
1731 'fn': '_.sortedLastIndexOf(hundredSortedValues, 0)',
1732 'teardown': 'function multiArrays(){}'
1736 /*--------------------------------------------------------------------------*/
1739 Benchmark.Suite('`_.sum`')
1741 lodash.sum(numbers)'
1748 /*--------------------------------------------------------------------------*/
1751 Benchmark.Suite('`_.template` (slow path)')
1753 'fn': 'lodash.template(tpl)(tplData)',
1754 'teardown': 'function template(){}'
1757 'fn': '_.template(tpl)(tplData)',
1758 'teardown': 'function template(){}'
1763 Benchmark.Suite('compiled template')
1765 'fn': 'lodashTpl(tplData)',
1766 'teardown': 'function template(){}'
1769 'fn': '_tpl(tplData)',
1770 'teardown': 'function template(){}'
1775 Benchmark.Suite('compiled template without a with-statement')
1777 'fn': 'lodashTplVerbose(tplData)',
1778 'teardown': 'function template(){}'
1781 'fn': '_tplVerbose(tplData)',
1782 'teardown': 'function template(){}'
1786 /*--------------------------------------------------------------------------*/
1789 Benchmark.Suite('`_.times`')
1792 lodash.times(limit, function(n) { result.push(n); })'
1796 _.times(limit, function(n) { result.push(n); })'
1800 /*--------------------------------------------------------------------------*/
1803 Benchmark.Suite('`_.toArray` with an array (edge case)')
1805 lodash.toArray(numbers)'
1813 Benchmark.Suite('`_.toArray` with an object')
1815 lodash.toArray(object)'
1822 /*--------------------------------------------------------------------------*/
1825 Benchmark.Suite('`_.toPairs`')
1827 lodash.toPairs(object)'
1834 /*--------------------------------------------------------------------------*/
1837 Benchmark.Suite('`_.unescape` string without html entities')
1839 lodash.unescape("`&`, `<`, `>`, `\\"`, and `\'`")'
1842 _.unescape("`&`, `<`, `>`, `\\"`, and `\'`")'
1847 Benchmark.Suite('`_.unescape` string with html entities')
1849 lodash.unescape("`&`, `<`, `>`, `"`, and `'`")'
1852 _.unescape("`&`, `<`, `>`, `"`, and `'`")'
1856 /*--------------------------------------------------------------------------*/
1859 Benchmark.Suite('`_.union`')
1861 lodash.union(numbers, twoNumbers, fourNumbers)'
1864 _.union(numbers, twoNumbers, fourNumbers)'
1869 Benchmark.Suite('`_.union` iterating an array of 200 elements')
1871 'fn': 'lodash.union(hundredValues, hundredValues2)',
1872 'teardown': 'function multiArrays(){}'
1875 'fn': '_.union(hundredValues, hundredValues2)',
1876 'teardown': 'function multiArrays(){}'
1880 /*--------------------------------------------------------------------------*/
1883 Benchmark.Suite('`_.uniq`')
1885 lodash.uniq(numbers.concat(twoNumbers, fourNumbers))'
1888 _.uniq(numbers.concat(twoNumbers, fourNumbers))'
1893 Benchmark.Suite('`_.uniq` iterating an array of 200 elements')
1895 'fn': 'lodash.uniq(twoHundredValues)',
1896 'teardown': 'function multiArrays(){}'
1899 'fn': '_.uniq(twoHundredValues)',
1900 'teardown': 'function multiArrays(){}'
1904 /*--------------------------------------------------------------------------*/
1907 Benchmark.Suite('`_.uniqBy`')
1909 lodash.uniqBy(numbers.concat(twoNumbers, fourNumbers), function(num) {\
1914 _.uniqBy(numbers.concat(twoNumbers, fourNumbers), function(num) {\
1920 /*--------------------------------------------------------------------------*/
1923 Benchmark.Suite('`_.values`')
1925 lodash.values(object)'
1932 /*--------------------------------------------------------------------------*/
1935 Benchmark.Suite('`_.without`')
1937 lodash.without(numbers, 9, 12, 14, 15)'
1940 _.without(numbers, 9, 12, 14, 15)'
1944 /*--------------------------------------------------------------------------*/
1947 Benchmark.Suite('`_.wrap` result called')
1949 'fn': 'lodashWrapped(2, 5)',
1950 'teardown': 'function wrap(){}'
1953 'fn': '_wrapped(2, 5)',
1954 'teardown': 'function wrap(){}'
1958 /*--------------------------------------------------------------------------*/
1961 Benchmark.Suite('`_.zip`')
1963 'fn': 'lodash.zip.apply(lodash, unzipped)',
1964 'teardown': 'function zip(){}'
1967 'fn': '_.zip.apply(_, unzipped)',
1968 'teardown': 'function zip(){}'
1972 /*--------------------------------------------------------------------------*/
1974 if (Benchmark.platform + '') {
1975 log(Benchmark.platform);
1977 // Expose `run` to be called later when executing in a browser.