1;(function() {
2  'use strict';
3
4  /** Used to access the Firebug Lite panel (set by `run`). */
5  var fbPanel;
6
7  /** Used as a safe reference for `undefined` in pre ES5 environments. */
8  var undefined;
9
10  /** Used as a reference to the global object. */
11  var root = typeof global == 'object' && global || this;
12
13  /** Method and object shortcuts. */
14  var phantom = root.phantom,
15      amd = root.define && define.amd,
16      argv = root.process && process.argv,
17      document = !phantom && root.document,
18      noop = function() {},
19      params = root.arguments,
20      system = root.system;
21
22  /** Add `console.log()` support for Rhino and RingoJS. */
23  var console = root.console || (root.console = { 'log': root.print });
24
25  /** The file path of the lodash file to test. */
26  var filePath = (function() {
27    var min = 0,
28        result = [];
29
30    if (phantom) {
31      result = params = phantom.args;
32    } else if (system) {
33      min = 1;
34      result = params = system.args;
35    } else if (argv) {
36      min = 2;
37      result = params = argv;
38    } else if (params) {
39      result = params;
40    }
41    var last = result[result.length - 1];
42    result = (result.length > min && !/perf(?:\.js)?$/.test(last)) ? last : '../lodash.js';
43
44    if (!amd) {
45      try {
46        result = require('fs').realpathSync(result);
47      } catch (e) {}
48
49      try {
50        result = require.resolve(result);
51      } catch (e) {}
52    }
53    return result;
54  }());
55
56  /** Used to match path separators. */
57  var rePathSeparator = /[\/\\]/;
58
59  /** Used to detect primitive types. */
60  var rePrimitive = /^(?:boolean|number|string|undefined)$/;
61
62  /** Used to match RegExp special characters. */
63  var reSpecialChars = /[.*+?^=!:${}()|[\]\/\\]/g;
64
65  /** The `ui` object. */
66  var ui = root.ui || (root.ui = {
67    'buildPath': basename(filePath, '.js'),
68    'otherPath': 'underscore'
69  });
70
71  /** The lodash build basename. */
72  var buildName = root.buildName = basename(ui.buildPath, '.js');
73
74  /** The other library basename. */
75  var otherName = root.otherName = (function() {
76    var result = basename(ui.otherPath, '.js');
77    return result + (result == buildName ? ' (2)' : '');
78  }());
79
80  /** Used to score performance. */
81  var score = { 'a': [], 'b': [] };
82
83  /** Used to queue benchmark suites. */
84  var suites = [];
85
86  /** Use a single "load" function. */
87  var load = (typeof require == 'function' && !amd)
88    ? require
89    : noop;
90
91  /** Load lodash. */
92  var lodash = root.lodash || (root.lodash = (
93    lodash = load(filePath) || root._,
94    lodash = lodash._ || lodash,
95    (lodash.runInContext ? lodash.runInContext(root) : lodash),
96    lodash.noConflict()
97  ));
98
99  /** Load Underscore. */
100  var _ = root.underscore || (root.underscore = (
101    _ = load('../vendor/underscore/underscore.js') || root._,
102    _._ || _
103  ));
104
105  /** Load Benchmark.js. */
106  var Benchmark = root.Benchmark || (root.Benchmark = (
107    Benchmark = load('../node_modules/benchmark/benchmark.js') || root.Benchmark,
108    Benchmark = Benchmark.Benchmark || Benchmark,
109    Benchmark.runInContext(lodash.extend({}, root, { '_': lodash }))
110  ));
111
112  /*--------------------------------------------------------------------------*/
113
114  /**
115   * Gets the basename of the given `filePath`. If the file `extension` is passed,
116   * it will be removed from the basename.
117   *
118   * @private
119   * @param {string} path The file path to inspect.
120   * @param {string} extension The extension to remove.
121   * @returns {string} Returns the basename.
122   */
123  function basename(filePath, extension) {
124    var result = (filePath || '').split(rePathSeparator).pop();
125    return (arguments.length < 2)
126      ? result
127      : result.replace(RegExp(extension.replace(reSpecialChars, '\\$&') + '$'), '');
128  }
129
130  /**
131   * Computes the geometric mean (log-average) of an array of values.
132   * See http://en.wikipedia.org/wiki/Geometric_mean#Relationship_with_arithmetic_mean_of_logarithms.
133   *
134   * @private
135   * @param {Array} array The array of values.
136   * @returns {number} The geometric mean.
137   */
138  function getGeometricMean(array) {
139    return Math.pow(Math.E, lodash.reduce(array, function(sum, x) {
140      return sum + Math.log(x);
141    }, 0) / array.length) || 0;
142  }
143
144  /**
145   * Gets the Hz, i.e. operations per second, of `bench` adjusted for the
146   * margin of error.
147   *
148   * @private
149   * @param {Object} bench The benchmark object.
150   * @returns {number} Returns the adjusted Hz.
151   */
152  function getHz(bench) {
153    var result = 1 / (bench.stats.mean + bench.stats.moe);
154    return isFinite(result) ? result : 0;
155  }
156
157  /**
158   * Host objects can return type values that are different from their actual
159   * data type. The objects we are concerned with usually return non-primitive
160   * types of "object", "function", or "unknown".
161   *
162   * @private
163   * @param {*} object The owner of the property.
164   * @param {string} property The property to check.
165   * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`.
166   */
167  function isHostType(object, property) {
168    if (object == null) {
169      return false;
170    }
171    var type = typeof object[property];
172    return !rePrimitive.test(type) && (type != 'object' || !!object[property]);
173  }
174
175  /**
176   * Logs text to the console.
177   *
178   * @private
179   * @param {string} text The text to log.
180   */
181  function log(text) {
182    console.log(text + '');
183    if (fbPanel) {
184      // Scroll the Firebug Lite panel down.
185      fbPanel.scrollTop = fbPanel.scrollHeight;
186    }
187  }
188
189  /**
190   * Runs all benchmark suites.
191   *
192   * @private (@public in the browser)
193   */
194  function run() {
195    fbPanel = (fbPanel = root.document && document.getElementById('FirebugUI')) &&
196      (fbPanel = (fbPanel = fbPanel.contentWindow || fbPanel.contentDocument).document || fbPanel) &&
197      fbPanel.getElementById('fbPanel1');
198
199    log('\nSit back and relax, this may take a while.');
200    suites[0].run({ 'async': true });
201  }
202
203  /*--------------------------------------------------------------------------*/
204
205  lodash.extend(Benchmark.Suite.options, {
206    'onStart': function() {
207      log('\n' + this.name + ':');
208    },
209    'onCycle': function(event) {
210      log(event.target);
211    },
212    'onComplete': function() {
213      for (var index = 0, length = this.length; index < length; index++) {
214        var bench = this[index];
215        if (bench.error) {
216          var errored = true;
217        }
218      }
219      if (errored) {
220        log('There was a problem, skipping...');
221      }
222      else {
223        var formatNumber = Benchmark.formatNumber,
224            fastest = this.filter('fastest'),
225            fastestHz = getHz(fastest[0]),
226            slowest = this.filter('slowest'),
227            slowestHz = getHz(slowest[0]),
228            aHz = getHz(this[0]),
229            bHz = getHz(this[1]);
230
231        if (fastest.length > 1) {
232          log('It\'s too close to call.');
233          aHz = bHz = slowestHz;
234        }
235        else {
236          var percent = ((fastestHz / slowestHz) - 1) * 100;
237
238          log(
239            fastest[0].name + ' is ' +
240            formatNumber(percent < 1 ? percent.toFixed(2) : Math.round(percent)) +
241            '% faster.'
242          );
243        }
244        // Add score adjusted for margin of error.
245        score.a.push(aHz);
246        score.b.push(bHz);
247      }
248      // Remove current suite from queue.
249      suites.shift();
250
251      if (suites.length) {
252        // Run next suite.
253        suites[0].run({ 'async': true });
254      }
255      else {
256        var aMeanHz = getGeometricMean(score.a),
257            bMeanHz = getGeometricMean(score.b),
258            fastestMeanHz = Math.max(aMeanHz, bMeanHz),
259            slowestMeanHz = Math.min(aMeanHz, bMeanHz),
260            xFaster = fastestMeanHz / slowestMeanHz,
261            percentFaster = formatNumber(Math.round((xFaster - 1) * 100)),
262            message = 'is ' + percentFaster + '% ' + (xFaster == 1 ? '' : '(' + formatNumber(xFaster.toFixed(2)) + 'x) ') + 'faster than';
263
264        // Report results.
265        if (aMeanHz >= bMeanHz) {
266          log('\n' + buildName + ' ' + message + ' ' + otherName + '.');
267        } else {
268          log('\n' + otherName + ' ' + message + ' ' + buildName + '.');
269        }
270      }
271    }
272  });
273
274  /*--------------------------------------------------------------------------*/
275
276  lodash.extend(Benchmark.options, {
277    'async': true,
278    'setup': '\
279      var _ = global.underscore,\
280          lodash = global.lodash,\
281          belt = this.name == buildName ? lodash : _;\
282      \
283      var date = new Date,\
284          limit = 50,\
285          regexp = /x/,\
286          object = {},\
287          objects = Array(limit),\
288          numbers = Array(limit),\
289          fourNumbers = [5, 25, 10, 30],\
290          nestedNumbers = [1, [2], [3, [[4]]]],\
291          nestedObjects = [{}, [{}], [{}, [[{}]]]],\
292          twoNumbers = [12, 23];\
293      \
294      for (var index = 0; index < limit; index++) {\
295        numbers[index] = index;\
296        object["key" + index] = index;\
297        objects[index] = { "num": index };\
298      }\
299      var strNumbers = numbers + "";\
300      \
301      if (typeof assign != "undefined") {\
302        var _assign = _.assign || _.extend,\
303            lodashAssign = lodash.assign;\
304      }\
305      if (typeof bind != "undefined") {\
306        var thisArg = { "name": "fred" };\
307        \
308        var func = function(greeting, punctuation) {\
309          return (greeting || "hi") + " " + this.name + (punctuation || ".");\
310        };\
311        \
312        var _boundNormal = _.bind(func, thisArg),\
313            _boundMultiple = _boundNormal,\
314            _boundPartial = _.bind(func, thisArg, "hi");\
315        \
316        var lodashBoundNormal = lodash.bind(func, thisArg),\
317            lodashBoundMultiple = lodashBoundNormal,\
318            lodashBoundPartial = lodash.bind(func, thisArg, "hi");\
319        \
320        for (index = 0; index < 10; index++) {\
321          _boundMultiple = _.bind(_boundMultiple, { "name": "fred" + index });\
322          lodashBoundMultiple = lodash.bind(lodashBoundMultiple, { "name": "fred" + index });\
323        }\
324      }\
325      if (typeof bindAll != "undefined") {\
326        var bindAllCount = -1,\
327            bindAllObjects = Array(this.count);\
328        \
329        var funcNames = belt.reject(belt.functions(belt).slice(0, 40), function(funcName) {\
330          return /^_/.test(funcName);\
331        });\
332        \
333        // Potentially expensive.\n\
334        for (index = 0; index < this.count; index++) {\
335          bindAllObjects[index] = belt.reduce(funcNames, function(object, funcName) {\
336            object[funcName] = belt[funcName];\
337            return object;\
338          }, {});\
339        }\
340      }\
341      if (typeof chaining != "undefined") {\
342        var even = function(v) { return v % 2 == 0; },\
343            square = function(v) { return v * v; };\
344        \
345        var largeArray = belt.range(10000),\
346            _chaining = _(largeArray).chain(),\
347            lodashChaining = lodash(largeArray).chain();\
348      }\
349      if (typeof compact != "undefined") {\
350        var uncompacted = numbers.slice();\
351        uncompacted[2] = false;\
352        uncompacted[6] = null;\
353        uncompacted[18] = "";\
354      }\
355      if (typeof flowRight != "undefined") {\
356        var compAddOne = function(n) { return n + 1; },\
357            compAddTwo = function(n) { return n + 2; },\
358            compAddThree = function(n) { return n + 3; };\
359        \
360        var _composed = _.flowRight && _.flowRight(compAddThree, compAddTwo, compAddOne),\
361            lodashComposed = lodash.flowRight && lodash.flowRight(compAddThree, compAddTwo, compAddOne);\
362      }\
363      if (typeof countBy != "undefined" || typeof omit != "undefined") {\
364        var wordToNumber = {\
365          "one": 1,\
366          "two": 2,\
367          "three": 3,\
368          "four": 4,\
369          "five": 5,\
370          "six": 6,\
371          "seven": 7,\
372          "eight": 8,\
373          "nine": 9,\
374          "ten": 10,\
375          "eleven": 11,\
376          "twelve": 12,\
377          "thirteen": 13,\
378          "fourteen": 14,\
379          "fifteen": 15,\
380          "sixteen": 16,\
381          "seventeen": 17,\
382          "eighteen": 18,\
383          "nineteen": 19,\
384          "twenty": 20,\
385          "twenty-one": 21,\
386          "twenty-two": 22,\
387          "twenty-three": 23,\
388          "twenty-four": 24,\
389          "twenty-five": 25,\
390          "twenty-six": 26,\
391          "twenty-seven": 27,\
392          "twenty-eight": 28,\
393          "twenty-nine": 29,\
394          "thirty": 30,\
395          "thirty-one": 31,\
396          "thirty-two": 32,\
397          "thirty-three": 33,\
398          "thirty-four": 34,\
399          "thirty-five": 35,\
400          "thirty-six": 36,\
401          "thirty-seven": 37,\
402          "thirty-eight": 38,\
403          "thirty-nine": 39,\
404          "forty": 40\
405        };\
406        \
407        var words = belt.keys(wordToNumber).slice(0, limit);\
408      }\
409      if (typeof flatten != "undefined") {\
410        var _flattenDeep = _.flatten([[1]])[0] !== 1,\
411            lodashFlattenDeep = lodash.flatten([[1]])[0] !== 1;\
412      }\
413      if (typeof isEqual != "undefined") {\
414        var objectOfPrimitives = {\
415          "boolean": true,\
416          "number": 1,\
417          "string": "a"\
418        };\
419        \
420        var objectOfObjects = {\
421          "boolean": new Boolean(true),\
422          "number": new Number(1),\
423          "string": new String("a")\
424        };\
425        \
426        var objectOfObjects2 = {\
427          "boolean": new Boolean(true),\
428          "number": new Number(1),\
429          "string": new String("A")\
430        };\
431        \
432        var object2 = {},\
433            object3 = {},\
434            objects2 = Array(limit),\
435            objects3 = Array(limit),\
436            numbers2 = Array(limit),\
437            numbers3 = Array(limit),\
438            nestedNumbers2 = [1, [2], [3, [[4]]]],\
439            nestedNumbers3 = [1, [2], [3, [[6]]]];\
440        \
441        for (index = 0; index < limit; index++) {\
442          object2["key" + index] = index;\
443          object3["key" + index] = index;\
444          objects2[index] = { "num": index };\
445          objects3[index] = { "num": index };\
446          numbers2[index] = index;\
447          numbers3[index] = index;\
448        }\
449        object3["key" + (limit - 1)] = -1;\
450        objects3[limit - 1].num = -1;\
451        numbers3[limit - 1] = -1;\
452      }\
453      if (typeof matches != "undefined") {\
454        var source = { "num": 9 };\
455        \
456        var _matcher = (_.matches || _.noop)(source),\
457            lodashMatcher = (lodash.matches || lodash.noop)(source);\
458      }\
459      if (typeof multiArrays != "undefined") {\
460        var twentyValues = belt.shuffle(belt.range(20)),\
461            fortyValues = belt.shuffle(belt.range(40)),\
462            hundredSortedValues = belt.range(100),\
463            hundredValues = belt.shuffle(hundredSortedValues),\
464            hundredValues2 = belt.shuffle(hundredValues),\
465            hundredTwentyValues = belt.shuffle(belt.range(120)),\
466            hundredTwentyValues2 = belt.shuffle(hundredTwentyValues),\
467            twoHundredValues = belt.shuffle(belt.range(200)),\
468            twoHundredValues2 = belt.shuffle(twoHundredValues);\
469      }\
470      if (typeof partial != "undefined") {\
471        var func = function(greeting, punctuation) {\
472          return greeting + " fred" + (punctuation || ".");\
473        };\
474        \
475        var _partial = _.partial(func, "hi"),\
476            lodashPartial = lodash.partial(func, "hi");\
477      }\
478      if (typeof template != "undefined") {\
479        var tplData = {\
480          "header1": "Header1",\
481          "header2": "Header2",\
482          "header3": "Header3",\
483          "header4": "Header4",\
484          "header5": "Header5",\
485          "header6": "Header6",\
486          "list": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]\
487        };\
488        \
489        var tpl =\
490          "<div>" +\
491          "<h1 class=\'header1\'><%= header1 %></h1>" +\
492          "<h2 class=\'header2\'><%= header2 %></h2>" +\
493          "<h3 class=\'header3\'><%= header3 %></h3>" +\
494          "<h4 class=\'header4\'><%= header4 %></h4>" +\
495          "<h5 class=\'header5\'><%= header5 %></h5>" +\
496          "<h6 class=\'header6\'><%= header6 %></h6>" +\
497          "<ul class=\'list\'>" +\
498          "<% for (var index = 0, length = list.length; index < length; index++) { %>" +\
499          "<li class=\'item\'><%= list[index] %></li>" +\
500          "<% } %>" +\
501          "</ul>" +\
502          "</div>";\
503        \
504        var tplVerbose =\
505          "<div>" +\
506          "<h1 class=\'header1\'><%= data.header1 %></h1>" +\
507          "<h2 class=\'header2\'><%= data.header2 %></h2>" +\
508          "<h3 class=\'header3\'><%= data.header3 %></h3>" +\
509          "<h4 class=\'header4\'><%= data.header4 %></h4>" +\
510          "<h5 class=\'header5\'><%= data.header5 %></h5>" +\
511          "<h6 class=\'header6\'><%= data.header6 %></h6>" +\
512          "<ul class=\'list\'>" +\
513          "<% for (var index = 0, length = data.list.length; index < length; index++) { %>" +\
514          "<li class=\'item\'><%= data.list[index] %></li>" +\
515          "<% } %>" +\
516          "</ul>" +\
517          "</div>";\
518        \
519        var settingsObject = { "variable": "data" };\
520        \
521        var _tpl = _.template(tpl),\
522            _tplVerbose = _.template(tplVerbose, null, settingsObject);\
523        \
524        var lodashTpl = lodash.template(tpl),\
525            lodashTplVerbose = lodash.template(tplVerbose, null, settingsObject);\
526      }\
527      if (typeof wrap != "undefined") {\
528        var add = function(a, b) {\
529          return a + b;\
530        };\
531        \
532        var average = function(func, a, b) {\
533          return (func(a, b) / 2).toFixed(2);\
534        };\
535        \
536        var _wrapped = _.wrap(add, average);\
537            lodashWrapped = lodash.wrap(add, average);\
538      }\
539      if (typeof zip != "undefined") {\
540        var unzipped = [["a", "b", "c"], [1, 2, 3], [true, false, true]];\
541      }'
542  });
543
544  /*--------------------------------------------------------------------------*/
545
546  suites.push(
547    Benchmark.Suite('`_(...).map(...).filter(...).take(...).value()`')
548      .add(buildName, {
549        'fn': 'lodashChaining.map(square).filter(even).take(100).value()',
550        'teardown': 'function chaining(){}'
551      })
552      .add(otherName, {
553        'fn': '_chaining.map(square).filter(even).take(100).value()',
554        'teardown': 'function chaining(){}'
555      })
556  );
557
558  /*--------------------------------------------------------------------------*/
559
560  suites.push(
561    Benchmark.Suite('`_.assign`')
562      .add(buildName, {
563        'fn': 'lodashAssign({}, { "a": 1, "b": 2, "c": 3 })',
564        'teardown': 'function assign(){}'
565      })
566      .add(otherName, {
567        'fn': '_assign({}, { "a": 1, "b": 2, "c": 3 })',
568        'teardown': 'function assign(){}'
569      })
570  );
571
572  suites.push(
573    Benchmark.Suite('`_.assign` with multiple sources')
574      .add(buildName, {
575        'fn': 'lodashAssign({}, { "a": 1, "b": 2 }, { "c": 3, "d": 4 })',
576        'teardown': 'function assign(){}'
577      })
578      .add(otherName, {
579        'fn': '_assign({}, { "a": 1, "b": 2 }, { "c": 3, "d": 4 })',
580        'teardown': 'function assign(){}'
581      })
582  );
583
584  /*--------------------------------------------------------------------------*/
585
586  suites.push(
587    Benchmark.Suite('`_.bind` (slow path)')
588      .add(buildName, {
589        'fn': 'lodash.bind(function() { return this.name; }, { "name": "fred" })',
590        'teardown': 'function bind(){}'
591      })
592      .add(otherName, {
593        'fn': '_.bind(function() { return this.name; }, { "name": "fred" })',
594        'teardown': 'function bind(){}'
595      })
596  );
597
598  suites.push(
599    Benchmark.Suite('bound call with arguments')
600      .add(buildName, {
601        'fn': 'lodashBoundNormal("hi", "!")',
602        'teardown': 'function bind(){}'
603      })
604      .add(otherName, {
605        'fn': '_boundNormal("hi", "!")',
606        'teardown': 'function bind(){}'
607      })
608  );
609
610  suites.push(
611    Benchmark.Suite('bound and partially applied call with arguments')
612      .add(buildName, {
613        'fn': 'lodashBoundPartial("!")',
614        'teardown': 'function bind(){}'
615      })
616      .add(otherName, {
617        'fn': '_boundPartial("!")',
618        'teardown': 'function bind(){}'
619      })
620  );
621
622  suites.push(
623    Benchmark.Suite('bound multiple times')
624      .add(buildName, {
625        'fn': 'lodashBoundMultiple()',
626        'teardown': 'function bind(){}'
627      })
628      .add(otherName, {
629        'fn': '_boundMultiple()',
630        'teardown': 'function bind(){}'
631      })
632  );
633
634  /*--------------------------------------------------------------------------*/
635
636  suites.push(
637    Benchmark.Suite('`_.bindAll`')
638      .add(buildName, {
639        'fn': 'lodash.bindAll(bindAllObjects[++bindAllCount], funcNames)',
640        'teardown': 'function bindAll(){}'
641      })
642      .add(otherName, {
643        'fn': '_.bindAll(bindAllObjects[++bindAllCount], funcNames)',
644        'teardown': 'function bindAll(){}'
645      })
646  );
647
648  /*--------------------------------------------------------------------------*/
649
650  suites.push(
651    Benchmark.Suite('`_.clone` with an array')
652      .add(buildName, '\
653        lodash.clone(numbers)'
654      )
655      .add(otherName, '\
656        _.clone(numbers)'
657      )
658  );
659
660  suites.push(
661    Benchmark.Suite('`_.clone` with an object')
662      .add(buildName, '\
663        lodash.clone(object)'
664      )
665      .add(otherName, '\
666        _.clone(object)'
667      )
668  );
669
670  /*--------------------------------------------------------------------------*/
671
672  suites.push(
673    Benchmark.Suite('`_.compact`')
674      .add(buildName, {
675        'fn': 'lodash.compact(uncompacted)',
676        'teardown': 'function compact(){}'
677      })
678      .add(otherName, {
679        'fn': '_.compact(uncompacted)',
680        'teardown': 'function compact(){}'
681      })
682  );
683
684  /*--------------------------------------------------------------------------*/
685
686  suites.push(
687    Benchmark.Suite('`_.countBy` with `callback` iterating an array')
688      .add(buildName, '\
689        lodash.countBy(numbers, function(num) { return num >> 1; })'
690      )
691      .add(otherName, '\
692        _.countBy(numbers, function(num) { return num >> 1; })'
693      )
694  );
695
696  suites.push(
697    Benchmark.Suite('`_.countBy` with `property` name iterating an array')
698      .add(buildName, {
699        'fn': 'lodash.countBy(words, "length")',
700        'teardown': 'function countBy(){}'
701      })
702      .add(otherName, {
703        'fn': '_.countBy(words, "length")',
704        'teardown': 'function countBy(){}'
705      })
706  );
707
708  suites.push(
709    Benchmark.Suite('`_.countBy` with `callback` iterating an object')
710      .add(buildName, {
711        'fn': 'lodash.countBy(wordToNumber, function(num) { return num >> 1; })',
712        'teardown': 'function countBy(){}'
713      })
714      .add(otherName, {
715        'fn': '_.countBy(wordToNumber, function(num) { return num >> 1; })',
716        'teardown': 'function countBy(){}'
717      })
718  );
719
720  /*--------------------------------------------------------------------------*/
721
722  suites.push(
723    Benchmark.Suite('`_.defaults`')
724      .add(buildName, '\
725        lodash.defaults({ "key2": 2, "key6": 6, "key18": 18 }, object)'
726      )
727      .add(otherName, '\
728        _.defaults({ "key2": 2, "key6": 6, "key18": 18 }, object)'
729      )
730  );
731
732  /*--------------------------------------------------------------------------*/
733
734  suites.push(
735    Benchmark.Suite('`_.difference`')
736      .add(buildName, '\
737        lodash.difference(numbers, twoNumbers, fourNumbers)'
738      )
739      .add(otherName, '\
740        _.difference(numbers, twoNumbers, fourNumbers)'
741      )
742  );
743
744  suites.push(
745    Benchmark.Suite('`_.difference` iterating 20 and 40 elements')
746      .add(buildName, {
747        'fn': 'lodash.difference(twentyValues, fortyValues)',
748        'teardown': 'function multiArrays(){}'
749      })
750      .add(otherName, {
751        'fn': '_.difference(twentyValues, fortyValues)',
752        'teardown': 'function multiArrays(){}'
753      })
754  );
755
756  suites.push(
757    Benchmark.Suite('`_.difference` iterating 200 elements')
758      .add(buildName, {
759        'fn': 'lodash.difference(twoHundredValues, twoHundredValues2)',
760        'teardown': 'function multiArrays(){}'
761      })
762      .add(otherName, {
763        'fn': '_.difference(twoHundredValues, twoHundredValues2)',
764        'teardown': 'function multiArrays(){}'
765      })
766  );
767
768  /*--------------------------------------------------------------------------*/
769
770  suites.push(
771    Benchmark.Suite('`_.each` iterating an array')
772      .add(buildName, '\
773        var result = [];\
774        lodash.each(numbers, function(num) {\
775          result.push(num * 2);\
776        })'
777      )
778      .add(otherName, '\
779        var result = [];\
780        _.each(numbers, function(num) {\
781          result.push(num * 2);\
782        })'
783      )
784  );
785
786  suites.push(
787    Benchmark.Suite('`_.each` iterating an object')
788      .add(buildName, '\
789        var result = [];\
790        lodash.each(object, function(num) {\
791          result.push(num * 2);\
792        })'
793      )
794      .add(otherName, '\
795        var result = [];\
796        _.each(object, function(num) {\
797          result.push(num * 2);\
798        })'
799      )
800  );
801
802  /*--------------------------------------------------------------------------*/
803
804  suites.push(
805    Benchmark.Suite('`_.every` iterating an array')
806      .add(buildName, '\
807        lodash.every(numbers, function(num) {\
808          return num < limit;\
809        })'
810      )
811      .add(otherName, '\
812        _.every(numbers, function(num) {\
813          return num < limit;\
814        })'
815      )
816  );
817
818  suites.push(
819    Benchmark.Suite('`_.every` iterating an object')
820      .add(buildName, '\
821        lodash.every(object, function(num) {\
822          return num < limit;\
823        })'
824      )
825      .add(otherName, '\
826        _.every(object, function(num) {\
827          return num < limit;\
828        })'
829      )
830  );
831
832  /*--------------------------------------------------------------------------*/
833
834  suites.push(
835    Benchmark.Suite('`_.filter` iterating an array')
836      .add(buildName, '\
837        lodash.filter(numbers, function(num) {\
838          return num % 2;\
839        })'
840      )
841      .add(otherName, '\
842        _.filter(numbers, function(num) {\
843          return num % 2;\
844        })'
845      )
846  );
847
848  suites.push(
849    Benchmark.Suite('`_.filter` iterating an object')
850      .add(buildName, '\
851        lodash.filter(object, function(num) {\
852          return num % 2\
853        })'
854      )
855      .add(otherName, '\
856        _.filter(object, function(num) {\
857          return num % 2\
858        })'
859      )
860  );
861
862  suites.push(
863    Benchmark.Suite('`_.filter` with `_.matches` shorthand')
864      .add(buildName, {
865        'fn': 'lodash.filter(objects, source)',
866        'teardown': 'function matches(){}'
867      })
868      .add(otherName, {
869        'fn': '_.filter(objects, source)',
870        'teardown': 'function matches(){}'
871      })
872  );
873
874  suites.push(
875    Benchmark.Suite('`_.filter` with `_.matches` predicate')
876      .add(buildName, {
877        'fn': 'lodash.filter(objects, lodashMatcher)',
878        'teardown': 'function matches(){}'
879      })
880      .add(otherName, {
881        'fn': '_.filter(objects, _matcher)',
882        'teardown': 'function matches(){}'
883      })
884  );
885
886  /*--------------------------------------------------------------------------*/
887
888  suites.push(
889    Benchmark.Suite('`_.find` iterating an array')
890      .add(buildName, '\
891        lodash.find(numbers, function(num) {\
892          return num === (limit - 1);\
893        })'
894      )
895      .add(otherName, '\
896        _.find(numbers, function(num) {\
897          return num === (limit - 1);\
898        })'
899      )
900  );
901
902  suites.push(
903    Benchmark.Suite('`_.find` iterating an object')
904      .add(buildName, '\
905        lodash.find(object, function(value, key) {\
906          return /\D9$/.test(key);\
907        })'
908      )
909      .add(otherName, '\
910        _.find(object, function(value, key) {\
911          return /\D9$/.test(key);\
912        })'
913      )
914  );
915
916  // Avoid Underscore induced `OutOfMemoryError` in Rhino and Ringo.
917  suites.push(
918    Benchmark.Suite('`_.find` with `_.matches` shorthand')
919      .add(buildName, {
920        'fn': 'lodash.find(objects, source)',
921        'teardown': 'function matches(){}'
922      })
923      .add(otherName, {
924        'fn': '_.find(objects, source)',
925        'teardown': 'function matches(){}'
926      })
927  );
928
929  /*--------------------------------------------------------------------------*/
930
931  suites.push(
932    Benchmark.Suite('`_.flatten`')
933      .add(buildName, {
934        'fn': 'lodash.flatten(nestedNumbers, !lodashFlattenDeep)',
935        'teardown': 'function flatten(){}'
936      })
937      .add(otherName, {
938        'fn': '_.flatten(nestedNumbers, !_flattenDeep)',
939        'teardown': 'function flatten(){}'
940      })
941  );
942
943  /*--------------------------------------------------------------------------*/
944
945  suites.push(
946    Benchmark.Suite('`_.flattenDeep` nested arrays of numbers')
947      .add(buildName, {
948        'fn': 'lodash.flattenDeep(nestedNumbers)',
949        'teardown': 'function flatten(){}'
950      })
951      .add(otherName, {
952        'fn': '_.flattenDeep(nestedNumbers)',
953        'teardown': 'function flatten(){}'
954      })
955  );
956
957  suites.push(
958    Benchmark.Suite('`_.flattenDeep` nest arrays of objects')
959      .add(buildName, {
960        'fn': 'lodash.flattenDeep(nestedObjects)',
961        'teardown': 'function flatten(){}'
962      })
963      .add(otherName, {
964        'fn': '_.flattenDeep(nestedObjects)',
965        'teardown': 'function flatten(){}'
966      })
967  );
968
969  /*--------------------------------------------------------------------------*/
970
971  suites.push(
972    Benchmark.Suite('`_.flowRight`')
973      .add(buildName, {
974        'fn': 'lodash.flowRight(compAddThree, compAddTwo, compAddOne)',
975        'teardown': 'function flowRight(){}'
976      })
977      .add(otherName, {
978        'fn': '_.flowRight(compAddThree, compAddTwo, compAddOne)',
979        'teardown': 'function flowRight(){}'
980      })
981  );
982
983  suites.push(
984    Benchmark.Suite('composed call')
985      .add(buildName, {
986        'fn': 'lodashComposed(0)',
987        'teardown': 'function flowRight(){}'
988      })
989      .add(otherName, {
990        'fn': '_composed(0)',
991        'teardown': 'function flowRight(){}'
992      })
993  );
994
995  /*--------------------------------------------------------------------------*/
996
997  suites.push(
998    Benchmark.Suite('`_.functions`')
999      .add(buildName, '\
1000        lodash.functions(lodash)'
1001      )
1002      .add(otherName, '\
1003        _.functions(lodash)'
1004      )
1005  );
1006
1007  /*--------------------------------------------------------------------------*/
1008
1009  suites.push(
1010    Benchmark.Suite('`_.groupBy` with `callback` iterating an array')
1011      .add(buildName, '\
1012        lodash.groupBy(numbers, function(num) { return num >> 1; })'
1013      )
1014      .add(otherName, '\
1015        _.groupBy(numbers, function(num) { return num >> 1; })'
1016      )
1017  );
1018
1019  suites.push(
1020    Benchmark.Suite('`_.groupBy` with `property` name iterating an array')
1021      .add(buildName, {
1022        'fn': 'lodash.groupBy(words, "length")',
1023        'teardown': 'function countBy(){}'
1024      })
1025      .add(otherName, {
1026        'fn': '_.groupBy(words, "length")',
1027        'teardown': 'function countBy(){}'
1028      })
1029  );
1030
1031  suites.push(
1032    Benchmark.Suite('`_.groupBy` with `callback` iterating an object')
1033      .add(buildName, {
1034        'fn': 'lodash.groupBy(wordToNumber, function(num) { return num >> 1; })',
1035        'teardown': 'function countBy(){}'
1036      })
1037      .add(otherName, {
1038        'fn': '_.groupBy(wordToNumber, function(num) { return num >> 1; })',
1039        'teardown': 'function countBy(){}'
1040      })
1041  );
1042
1043  /*--------------------------------------------------------------------------*/
1044
1045  suites.push(
1046    Benchmark.Suite('`_.includes` searching an array')
1047      .add(buildName, '\
1048        lodash.includes(numbers, limit - 1)'
1049      )
1050      .add(otherName, '\
1051        _.includes(numbers, limit - 1)'
1052      )
1053  );
1054
1055  suites.push(
1056    Benchmark.Suite('`_.includes` searching an object')
1057      .add(buildName, '\
1058        lodash.includes(object, limit - 1)'
1059      )
1060      .add(otherName, '\
1061        _.includes(object, limit - 1)'
1062      )
1063  );
1064
1065  if (lodash.includes('ab', 'ab') && _.includes('ab', 'ab')) {
1066    suites.push(
1067      Benchmark.Suite('`_.includes` searching a string')
1068        .add(buildName, '\
1069          lodash.includes(strNumbers, "," + (limit - 1))'
1070        )
1071        .add(otherName, '\
1072          _.includes(strNumbers, "," + (limit - 1))'
1073        )
1074    );
1075  }
1076
1077  /*--------------------------------------------------------------------------*/
1078
1079  suites.push(
1080    Benchmark.Suite('`_.indexOf`')
1081      .add(buildName, {
1082        'fn': 'lodash.indexOf(hundredSortedValues, 99)',
1083        'teardown': 'function multiArrays(){}'
1084      })
1085      .add(otherName, {
1086        'fn': '_.indexOf(hundredSortedValues, 99)',
1087        'teardown': 'function multiArrays(){}'
1088      })
1089  );
1090
1091  /*--------------------------------------------------------------------------*/
1092
1093  suites.push(
1094    Benchmark.Suite('`_.intersection`')
1095      .add(buildName, '\
1096        lodash.intersection(numbers, twoNumbers, fourNumbers)'
1097      )
1098      .add(otherName, '\
1099        _.intersection(numbers, twoNumbers, fourNumbers)'
1100      )
1101  );
1102
1103  suites.push(
1104    Benchmark.Suite('`_.intersection` iterating 120 elements')
1105      .add(buildName, {
1106        'fn': 'lodash.intersection(hundredTwentyValues, hundredTwentyValues2)',
1107        'teardown': 'function multiArrays(){}'
1108      })
1109      .add(otherName, {
1110        'fn': '_.intersection(hundredTwentyValues, hundredTwentyValues2)',
1111        'teardown': 'function multiArrays(){}'
1112      })
1113  );
1114
1115  /*--------------------------------------------------------------------------*/
1116
1117  suites.push(
1118    Benchmark.Suite('`_.invert`')
1119      .add(buildName, '\
1120        lodash.invert(object)'
1121      )
1122      .add(otherName, '\
1123        _.invert(object)'
1124      )
1125  );
1126
1127  /*--------------------------------------------------------------------------*/
1128
1129  suites.push(
1130    Benchmark.Suite('`_.invokeMap` iterating an array')
1131      .add(buildName, '\
1132        lodash.invokeMap(numbers, "toFixed")'
1133      )
1134      .add(otherName, '\
1135        _.invokeMap(numbers, "toFixed")'
1136      )
1137  );
1138
1139  suites.push(
1140    Benchmark.Suite('`_.invokeMap` with arguments iterating an array')
1141      .add(buildName, '\
1142        lodash.invokeMap(numbers, "toFixed", 1)'
1143      )
1144      .add(otherName, '\
1145        _.invokeMap(numbers, "toFixed", 1)'
1146      )
1147  );
1148
1149  suites.push(
1150    Benchmark.Suite('`_.invokeMap` with a function for `path` iterating an array')
1151      .add(buildName, '\
1152        lodash.invokeMap(numbers, Number.prototype.toFixed, 1)'
1153      )
1154      .add(otherName, '\
1155        _.invokeMap(numbers, Number.prototype.toFixed, 1)'
1156      )
1157  );
1158
1159  suites.push(
1160    Benchmark.Suite('`_.invokeMap` iterating an object')
1161      .add(buildName, '\
1162        lodash.invokeMap(object, "toFixed", 1)'
1163      )
1164      .add(otherName, '\
1165        _.invokeMap(object, "toFixed", 1)'
1166      )
1167  );
1168
1169  /*--------------------------------------------------------------------------*/
1170
1171  suites.push(
1172    Benchmark.Suite('`_.isEqual` comparing primitives')
1173      .add(buildName, {
1174        'fn': '\
1175          lodash.isEqual(1, "1");\
1176          lodash.isEqual(1, 1)',
1177        'teardown': 'function isEqual(){}'
1178      })
1179      .add(otherName, {
1180        'fn': '\
1181          _.isEqual(1, "1");\
1182          _.isEqual(1, 1);',
1183        'teardown': 'function isEqual(){}'
1184      })
1185  );
1186
1187  suites.push(
1188    Benchmark.Suite('`_.isEqual` comparing primitives and their object counterparts (edge case)')
1189      .add(buildName, {
1190        'fn': '\
1191          lodash.isEqual(objectOfPrimitives, objectOfObjects);\
1192          lodash.isEqual(objectOfPrimitives, objectOfObjects2)',
1193        'teardown': 'function isEqual(){}'
1194      })
1195      .add(otherName, {
1196        'fn': '\
1197          _.isEqual(objectOfPrimitives, objectOfObjects);\
1198          _.isEqual(objectOfPrimitives, objectOfObjects2)',
1199        'teardown': 'function isEqual(){}'
1200      })
1201  );
1202
1203  suites.push(
1204    Benchmark.Suite('`_.isEqual` comparing arrays')
1205      .add(buildName, {
1206        'fn': '\
1207          lodash.isEqual(numbers, numbers2);\
1208          lodash.isEqual(numbers2, numbers3)',
1209        'teardown': 'function isEqual(){}'
1210      })
1211      .add(otherName, {
1212        'fn': '\
1213          _.isEqual(numbers, numbers2);\
1214          _.isEqual(numbers2, numbers3)',
1215        'teardown': 'function isEqual(){}'
1216      })
1217  );
1218
1219  suites.push(
1220    Benchmark.Suite('`_.isEqual` comparing nested arrays')
1221      .add(buildName, {
1222        'fn': '\
1223          lodash.isEqual(nestedNumbers, nestedNumbers2);\
1224          lodash.isEqual(nestedNumbers2, nestedNumbers3)',
1225        'teardown': 'function isEqual(){}'
1226      })
1227      .add(otherName, {
1228        'fn': '\
1229          _.isEqual(nestedNumbers, nestedNumbers2);\
1230          _.isEqual(nestedNumbers2, nestedNumbers3)',
1231        'teardown': 'function isEqual(){}'
1232      })
1233  );
1234
1235  suites.push(
1236    Benchmark.Suite('`_.isEqual` comparing arrays of objects')
1237      .add(buildName, {
1238        'fn': '\
1239          lodash.isEqual(objects, objects2);\
1240          lodash.isEqual(objects2, objects3)',
1241        'teardown': 'function isEqual(){}'
1242      })
1243      .add(otherName, {
1244        'fn': '\
1245          _.isEqual(objects, objects2);\
1246          _.isEqual(objects2, objects3)',
1247        'teardown': 'function isEqual(){}'
1248      })
1249  );
1250
1251  suites.push(
1252    Benchmark.Suite('`_.isEqual` comparing objects')
1253      .add(buildName, {
1254        'fn': '\
1255          lodash.isEqual(object, object2);\
1256          lodash.isEqual(object2, object3)',
1257        'teardown': 'function isEqual(){}'
1258      })
1259      .add(otherName, {
1260        'fn': '\
1261          _.isEqual(object, object2);\
1262          _.isEqual(object2, object3)',
1263        'teardown': 'function isEqual(){}'
1264      })
1265  );
1266
1267  /*--------------------------------------------------------------------------*/
1268
1269  suites.push(
1270    Benchmark.Suite('`_.isArguments`, `_.isDate`, `_.isFunction`, `_.isNumber`, `_.isObject`, `_.isRegExp`')
1271      .add(buildName, '\
1272        lodash.isArguments(arguments);\
1273        lodash.isArguments(object);\
1274        lodash.isDate(date);\
1275        lodash.isDate(object);\
1276        lodash.isFunction(lodash);\
1277        lodash.isFunction(object);\
1278        lodash.isNumber(1);\
1279        lodash.isNumber(object);\
1280        lodash.isObject(object);\
1281        lodash.isObject(1);\
1282        lodash.isRegExp(regexp);\
1283        lodash.isRegExp(object)'
1284      )
1285      .add(otherName, '\
1286        _.isArguments(arguments);\
1287        _.isArguments(object);\
1288        _.isDate(date);\
1289        _.isDate(object);\
1290        _.isFunction(_);\
1291        _.isFunction(object);\
1292        _.isNumber(1);\
1293        _.isNumber(object);\
1294        _.isObject(object);\
1295        _.isObject(1);\
1296        _.isRegExp(regexp);\
1297        _.isRegExp(object)'
1298      )
1299  );
1300
1301  /*--------------------------------------------------------------------------*/
1302
1303  suites.push(
1304    Benchmark.Suite('`_.keys` (uses native `Object.keys` if available)')
1305      .add(buildName, '\
1306        lodash.keys(object)'
1307      )
1308      .add(otherName, '\
1309        _.keys(object)'
1310      )
1311  );
1312
1313  /*--------------------------------------------------------------------------*/
1314
1315  suites.push(
1316    Benchmark.Suite('`_.lastIndexOf`')
1317      .add(buildName, {
1318        'fn': 'lodash.lastIndexOf(hundredSortedValues, 0)',
1319        'teardown': 'function multiArrays(){}'
1320      })
1321      .add(otherName, {
1322        'fn': '_.lastIndexOf(hundredSortedValues, 0)',
1323        'teardown': 'function multiArrays(){}'
1324      })
1325  );
1326
1327  /*--------------------------------------------------------------------------*/
1328
1329  suites.push(
1330    Benchmark.Suite('`_.map` iterating an array')
1331      .add(buildName, '\
1332        lodash.map(objects, function(value) {\
1333          return value.num;\
1334        })'
1335      )
1336      .add(otherName, '\
1337        _.map(objects, function(value) {\
1338          return value.num;\
1339        })'
1340      )
1341  );
1342
1343  suites.push(
1344    Benchmark.Suite('`_.map` iterating an object')
1345      .add(buildName, '\
1346        lodash.map(object, function(value) {\
1347          return value;\
1348        })'
1349      )
1350      .add(otherName, '\
1351        _.map(object, function(value) {\
1352          return value;\
1353        })'
1354      )
1355  );
1356
1357  suites.push(
1358    Benchmark.Suite('`_.map` with `_.property` shorthand')
1359      .add(buildName, '\
1360        lodash.map(objects, "num")'
1361      )
1362      .add(otherName, '\
1363        _.map(objects, "num")'
1364      )
1365  );
1366
1367  /*--------------------------------------------------------------------------*/
1368
1369  suites.push(
1370    Benchmark.Suite('`_.max`')
1371      .add(buildName, '\
1372        lodash.max(numbers)'
1373      )
1374      .add(otherName, '\
1375        _.max(numbers)'
1376      )
1377  );
1378
1379  /*--------------------------------------------------------------------------*/
1380
1381  suites.push(
1382    Benchmark.Suite('`_.min`')
1383      .add(buildName, '\
1384        lodash.min(numbers)'
1385      )
1386      .add(otherName, '\
1387        _.min(numbers)'
1388      )
1389  );
1390
1391  /*--------------------------------------------------------------------------*/
1392
1393  suites.push(
1394    Benchmark.Suite('`_.omit` iterating 20 properties, omitting 2 keys')
1395      .add(buildName, '\
1396        lodash.omit(object, "key6", "key13")'
1397      )
1398      .add(otherName, '\
1399        _.omit(object, "key6", "key13")'
1400      )
1401  );
1402
1403  suites.push(
1404    Benchmark.Suite('`_.omit` iterating 40 properties, omitting 20 keys')
1405      .add(buildName, {
1406        'fn': 'lodash.omit(wordToNumber, words)',
1407        'teardown': 'function omit(){}'
1408      })
1409      .add(otherName, {
1410        'fn': '_.omit(wordToNumber, words)',
1411        'teardown': 'function omit(){}'
1412      })
1413  );
1414
1415  /*--------------------------------------------------------------------------*/
1416
1417  suites.push(
1418    Benchmark.Suite('`_.partial` (slow path)')
1419      .add(buildName, {
1420        'fn': 'lodash.partial(function(greeting) { return greeting + " " + this.name; }, "hi")',
1421        'teardown': 'function partial(){}'
1422      })
1423      .add(otherName, {
1424        'fn': '_.partial(function(greeting) { return greeting + " " + this.name; }, "hi")',
1425        'teardown': 'function partial(){}'
1426      })
1427  );
1428
1429  suites.push(
1430    Benchmark.Suite('partially applied call with arguments')
1431      .add(buildName, {
1432        'fn': 'lodashPartial("!")',
1433        'teardown': 'function partial(){}'
1434      })
1435      .add(otherName, {
1436        'fn': '_partial("!")',
1437        'teardown': 'function partial(){}'
1438      })
1439  );
1440
1441  /*--------------------------------------------------------------------------*/
1442
1443  suites.push(
1444    Benchmark.Suite('`_.partition` iterating an array')
1445      .add(buildName, '\
1446        lodash.partition(numbers, function(num) {\
1447          return num % 2;\
1448        })'
1449      )
1450      .add(otherName, '\
1451        _.partition(numbers, function(num) {\
1452          return num % 2;\
1453        })'
1454      )
1455  );
1456
1457  suites.push(
1458    Benchmark.Suite('`_.partition` iterating an object')
1459      .add(buildName, '\
1460        lodash.partition(object, function(num) {\
1461          return num % 2;\
1462        })'
1463      )
1464      .add(otherName, '\
1465        _.partition(object, function(num) {\
1466          return num % 2;\
1467        })'
1468      )
1469  );
1470
1471  /*--------------------------------------------------------------------------*/
1472
1473  suites.push(
1474    Benchmark.Suite('`_.pick`')
1475      .add(buildName, '\
1476        lodash.pick(object, "key6", "key13")'
1477      )
1478      .add(otherName, '\
1479        _.pick(object, "key6", "key13")'
1480      )
1481  );
1482
1483  /*--------------------------------------------------------------------------*/
1484
1485  suites.push(
1486    Benchmark.Suite('`_.reduce` iterating an array')
1487      .add(buildName, '\
1488        lodash.reduce(numbers, function(result, value, index) {\
1489          result[index] = value;\
1490          return result;\
1491        }, {})'
1492      )
1493      .add(otherName, '\
1494        _.reduce(numbers, function(result, value, index) {\
1495          result[index] = value;\
1496          return result;\
1497        }, {})'
1498      )
1499  );
1500
1501  suites.push(
1502    Benchmark.Suite('`_.reduce` iterating an object')
1503      .add(buildName, '\
1504        lodash.reduce(object, function(result, value, key) {\
1505          result.push(key, value);\
1506          return result;\
1507        }, [])'
1508      )
1509      .add(otherName, '\
1510        _.reduce(object, function(result, value, key) {\
1511          result.push(key, value);\
1512          return result;\
1513        }, [])'
1514      )
1515  );
1516
1517  /*--------------------------------------------------------------------------*/
1518
1519  suites.push(
1520    Benchmark.Suite('`_.reduceRight` iterating an array')
1521      .add(buildName, '\
1522        lodash.reduceRight(numbers, function(result, value, index) {\
1523          result[index] = value;\
1524          return result;\
1525        }, {})'
1526      )
1527      .add(otherName, '\
1528        _.reduceRight(numbers, function(result, value, index) {\
1529          result[index] = value;\
1530          return result;\
1531        }, {})'
1532      )
1533  );
1534
1535  suites.push(
1536    Benchmark.Suite('`_.reduceRight` iterating an object')
1537      .add(buildName, '\
1538        lodash.reduceRight(object, function(result, value, key) {\
1539          result.push(key, value);\
1540          return result;\
1541        }, [])'
1542      )
1543      .add(otherName, '\
1544        _.reduceRight(object, function(result, value, key) {\
1545          result.push(key, value);\
1546          return result;\
1547        }, [])'
1548      )
1549  );
1550
1551  /*--------------------------------------------------------------------------*/
1552
1553  suites.push(
1554    Benchmark.Suite('`_.reject` iterating an array')
1555      .add(buildName, '\
1556        lodash.reject(numbers, function(num) {\
1557          return num % 2;\
1558        })'
1559      )
1560      .add(otherName, '\
1561        _.reject(numbers, function(num) {\
1562          return num % 2;\
1563        })'
1564      )
1565  );
1566
1567  suites.push(
1568    Benchmark.Suite('`_.reject` iterating an object')
1569      .add(buildName, '\
1570        lodash.reject(object, function(num) {\
1571          return num % 2;\
1572        })'
1573      )
1574      .add(otherName, '\
1575        _.reject(object, function(num) {\
1576          return num % 2;\
1577        })'
1578      )
1579  );
1580
1581  /*--------------------------------------------------------------------------*/
1582
1583  suites.push(
1584    Benchmark.Suite('`_.sampleSize`')
1585      .add(buildName, '\
1586        lodash.sampleSize(numbers, limit / 2)'
1587      )
1588      .add(otherName, '\
1589        _.sampleSize(numbers, limit / 2)'
1590      )
1591  );
1592
1593  /*--------------------------------------------------------------------------*/
1594
1595  suites.push(
1596    Benchmark.Suite('`_.shuffle`')
1597      .add(buildName, '\
1598        lodash.shuffle(numbers)'
1599      )
1600      .add(otherName, '\
1601        _.shuffle(numbers)'
1602      )
1603  );
1604
1605  /*--------------------------------------------------------------------------*/
1606
1607  suites.push(
1608    Benchmark.Suite('`_.size` with an object')
1609      .add(buildName, '\
1610        lodash.size(object)'
1611      )
1612      .add(otherName, '\
1613        _.size(object)'
1614      )
1615  );
1616
1617  /*--------------------------------------------------------------------------*/
1618
1619  suites.push(
1620    Benchmark.Suite('`_.some` iterating an array')
1621      .add(buildName, '\
1622        lodash.some(numbers, function(num) {\
1623          return num == (limit - 1);\
1624        })'
1625      )
1626      .add(otherName, '\
1627        _.some(numbers, function(num) {\
1628          return num == (limit - 1);\
1629        })'
1630      )
1631  );
1632
1633  suites.push(
1634    Benchmark.Suite('`_.some` iterating an object')
1635      .add(buildName, '\
1636        lodash.some(object, function(num) {\
1637          return num == (limit - 1);\
1638        })'
1639      )
1640      .add(otherName, '\
1641        _.some(object, function(num) {\
1642          return num == (limit - 1);\
1643        })'
1644      )
1645  );
1646
1647  /*--------------------------------------------------------------------------*/
1648
1649  suites.push(
1650    Benchmark.Suite('`_.sortBy` with `callback`')
1651      .add(buildName, '\
1652        lodash.sortBy(numbers, function(num) { return Math.sin(num); })'
1653      )
1654      .add(otherName, '\
1655        _.sortBy(numbers, function(num) { return Math.sin(num); })'
1656      )
1657  );
1658
1659  suites.push(
1660    Benchmark.Suite('`_.sortBy` with `property` name')
1661      .add(buildName, {
1662        'fn': 'lodash.sortBy(words, "length")',
1663        'teardown': 'function countBy(){}'
1664      })
1665      .add(otherName, {
1666        'fn': '_.sortBy(words, "length")',
1667        'teardown': 'function countBy(){}'
1668      })
1669  );
1670
1671  /*--------------------------------------------------------------------------*/
1672
1673  suites.push(
1674    Benchmark.Suite('`_.sortedIndex`')
1675      .add(buildName, '\
1676        lodash.sortedIndex(numbers, limit)'
1677      )
1678      .add(otherName, '\
1679        _.sortedIndex(numbers, limit)'
1680      )
1681  );
1682
1683  /*--------------------------------------------------------------------------*/
1684
1685  suites.push(
1686    Benchmark.Suite('`_.sortedIndexBy`')
1687      .add(buildName, {
1688        'fn': '\
1689          lodash.sortedIndexBy(words, "twenty-five", function(value) {\
1690            return wordToNumber[value];\
1691          })',
1692        'teardown': 'function countBy(){}'
1693      })
1694      .add(otherName, {
1695        'fn': '\
1696          _.sortedIndexBy(words, "twenty-five", function(value) {\
1697            return wordToNumber[value];\
1698          })',
1699        'teardown': 'function countBy(){}'
1700      })
1701  );
1702
1703  /*--------------------------------------------------------------------------*/
1704
1705  suites.push(
1706    Benchmark.Suite('`_.sortedIndexOf`')
1707      .add(buildName, {
1708        'fn': 'lodash.sortedIndexOf(hundredSortedValues, 99)',
1709        'teardown': 'function multiArrays(){}'
1710      })
1711      .add(otherName, {
1712        'fn': '_.sortedIndexOf(hundredSortedValues, 99)',
1713        'teardown': 'function multiArrays(){}'
1714      })
1715  );
1716
1717  /*--------------------------------------------------------------------------*/
1718
1719  suites.push(
1720    Benchmark.Suite('`_.sortedLastIndexOf`')
1721      .add(buildName, {
1722        'fn': 'lodash.sortedLastIndexOf(hundredSortedValues, 0)',
1723        'teardown': 'function multiArrays(){}'
1724      })
1725      .add(otherName, {
1726        'fn': '_.sortedLastIndexOf(hundredSortedValues, 0)',
1727        'teardown': 'function multiArrays(){}'
1728      })
1729  );
1730
1731  /*--------------------------------------------------------------------------*/
1732
1733  suites.push(
1734    Benchmark.Suite('`_.sum`')
1735      .add(buildName, '\
1736        lodash.sum(numbers)'
1737      )
1738      .add(otherName, '\
1739        _.sum(numbers)'
1740      )
1741  );
1742
1743  /*--------------------------------------------------------------------------*/
1744
1745  suites.push(
1746    Benchmark.Suite('`_.template` (slow path)')
1747      .add(buildName, {
1748        'fn': 'lodash.template(tpl)(tplData)',
1749        'teardown': 'function template(){}'
1750      })
1751      .add(otherName, {
1752        'fn': '_.template(tpl)(tplData)',
1753        'teardown': 'function template(){}'
1754      })
1755  );
1756
1757  suites.push(
1758    Benchmark.Suite('compiled template')
1759      .add(buildName, {
1760        'fn': 'lodashTpl(tplData)',
1761        'teardown': 'function template(){}'
1762      })
1763      .add(otherName, {
1764        'fn': '_tpl(tplData)',
1765        'teardown': 'function template(){}'
1766      })
1767  );
1768
1769  suites.push(
1770    Benchmark.Suite('compiled template without a with-statement')
1771      .add(buildName, {
1772        'fn': 'lodashTplVerbose(tplData)',
1773        'teardown': 'function template(){}'
1774      })
1775      .add(otherName, {
1776        'fn': '_tplVerbose(tplData)',
1777        'teardown': 'function template(){}'
1778      })
1779  );
1780
1781  /*--------------------------------------------------------------------------*/
1782
1783  suites.push(
1784    Benchmark.Suite('`_.times`')
1785      .add(buildName, '\
1786        var result = [];\
1787        lodash.times(limit, function(n) { result.push(n); })'
1788      )
1789      .add(otherName, '\
1790        var result = [];\
1791        _.times(limit, function(n) { result.push(n); })'
1792      )
1793  );
1794
1795  /*--------------------------------------------------------------------------*/
1796
1797  suites.push(
1798    Benchmark.Suite('`_.toArray` with an array (edge case)')
1799      .add(buildName, '\
1800        lodash.toArray(numbers)'
1801      )
1802      .add(otherName, '\
1803        _.toArray(numbers)'
1804      )
1805  );
1806
1807  suites.push(
1808    Benchmark.Suite('`_.toArray` with an object')
1809      .add(buildName, '\
1810        lodash.toArray(object)'
1811      )
1812      .add(otherName, '\
1813        _.toArray(object)'
1814      )
1815  );
1816
1817  /*--------------------------------------------------------------------------*/
1818
1819  suites.push(
1820    Benchmark.Suite('`_.toPairs`')
1821      .add(buildName, '\
1822        lodash.toPairs(object)'
1823      )
1824      .add(otherName, '\
1825        _.toPairs(object)'
1826      )
1827  );
1828
1829  /*--------------------------------------------------------------------------*/
1830
1831  suites.push(
1832    Benchmark.Suite('`_.unescape` string without html entities')
1833      .add(buildName, '\
1834        lodash.unescape("`&`, `<`, `>`, `\\"`, and `\'`")'
1835      )
1836      .add(otherName, '\
1837        _.unescape("`&`, `<`, `>`, `\\"`, and `\'`")'
1838      )
1839  );
1840
1841  suites.push(
1842    Benchmark.Suite('`_.unescape` string with html entities')
1843      .add(buildName, '\
1844        lodash.unescape("`&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;`")'
1845      )
1846      .add(otherName, '\
1847        _.unescape("`&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;`")'
1848      )
1849  );
1850
1851  /*--------------------------------------------------------------------------*/
1852
1853  suites.push(
1854    Benchmark.Suite('`_.union`')
1855      .add(buildName, '\
1856        lodash.union(numbers, twoNumbers, fourNumbers)'
1857      )
1858      .add(otherName, '\
1859        _.union(numbers, twoNumbers, fourNumbers)'
1860      )
1861  );
1862
1863  suites.push(
1864    Benchmark.Suite('`_.union` iterating an array of 200 elements')
1865      .add(buildName, {
1866        'fn': 'lodash.union(hundredValues, hundredValues2)',
1867        'teardown': 'function multiArrays(){}'
1868      })
1869      .add(otherName, {
1870        'fn': '_.union(hundredValues, hundredValues2)',
1871        'teardown': 'function multiArrays(){}'
1872      })
1873  );
1874
1875  /*--------------------------------------------------------------------------*/
1876
1877  suites.push(
1878    Benchmark.Suite('`_.uniq`')
1879      .add(buildName, '\
1880        lodash.uniq(numbers.concat(twoNumbers, fourNumbers))'
1881      )
1882      .add(otherName, '\
1883        _.uniq(numbers.concat(twoNumbers, fourNumbers))'
1884      )
1885  );
1886
1887  suites.push(
1888    Benchmark.Suite('`_.uniq` iterating an array of 200 elements')
1889      .add(buildName, {
1890        'fn': 'lodash.uniq(twoHundredValues)',
1891        'teardown': 'function multiArrays(){}'
1892      })
1893      .add(otherName, {
1894        'fn': '_.uniq(twoHundredValues)',
1895        'teardown': 'function multiArrays(){}'
1896      })
1897  );
1898
1899  /*--------------------------------------------------------------------------*/
1900
1901  suites.push(
1902    Benchmark.Suite('`_.uniqBy`')
1903      .add(buildName, '\
1904        lodash.uniqBy(numbers.concat(twoNumbers, fourNumbers), function(num) {\
1905          return num % 2;\
1906        })'
1907      )
1908      .add(otherName, '\
1909        _.uniqBy(numbers.concat(twoNumbers, fourNumbers), function(num) {\
1910          return num % 2;\
1911        })'
1912      )
1913  );
1914
1915  /*--------------------------------------------------------------------------*/
1916
1917  suites.push(
1918    Benchmark.Suite('`_.values`')
1919      .add(buildName, '\
1920        lodash.values(object)'
1921      )
1922      .add(otherName, '\
1923        _.values(object)'
1924      )
1925  );
1926
1927  /*--------------------------------------------------------------------------*/
1928
1929  suites.push(
1930    Benchmark.Suite('`_.without`')
1931      .add(buildName, '\
1932        lodash.without(numbers, 9, 12, 14, 15)'
1933      )
1934      .add(otherName, '\
1935        _.without(numbers, 9, 12, 14, 15)'
1936      )
1937  );
1938
1939  /*--------------------------------------------------------------------------*/
1940
1941  suites.push(
1942    Benchmark.Suite('`_.wrap` result called')
1943      .add(buildName, {
1944        'fn': 'lodashWrapped(2, 5)',
1945        'teardown': 'function wrap(){}'
1946      })
1947      .add(otherName, {
1948        'fn': '_wrapped(2, 5)',
1949        'teardown': 'function wrap(){}'
1950      })
1951  );
1952
1953  /*--------------------------------------------------------------------------*/
1954
1955  suites.push(
1956    Benchmark.Suite('`_.zip`')
1957      .add(buildName, {
1958        'fn': 'lodash.zip.apply(lodash, unzipped)',
1959        'teardown': 'function zip(){}'
1960      })
1961      .add(otherName, {
1962        'fn': '_.zip.apply(_, unzipped)',
1963        'teardown': 'function zip(){}'
1964      })
1965  );
1966
1967  /*--------------------------------------------------------------------------*/
1968
1969  if (Benchmark.platform + '') {
1970    log(Benchmark.platform);
1971  }
1972  // Expose `run` to be called later when executing in a browser.
1973  if (document) {
1974    root.run = run;
1975  } else {
1976    run();
1977  }
1978}.call(this));
1979