From 8c7fcb7781c89cc2d41c415ff5fbb755bbd4000c Mon Sep 17 00:00:00 2001 From: Noah Sloan Date: Tue, 8 Dec 2009 14:11:28 -0600 Subject: [PATCH 1/6] cache is string and toString to improve performance --- underscore.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/underscore.js b/underscore.js index 51398635d..b94cc0f9b 100644 --- a/underscore.js +++ b/underscore.js @@ -478,8 +478,9 @@ // Define the isArray, isDate, isFunction, isNumber, isRegExp, and // isString functions based on their toString identifiers. _.each(['Array', 'Date', 'Function', 'Number', 'RegExp', 'String'], function(type) { + var toString = Object.prototype.toString, typeString = '[object ' + type + ']'; _['is' + type] = function(obj) { - return Object.prototype.toString.call(obj) == '[object ' + type + ']'; + return toString.call(obj) == typeString; }; }); From 38cae13d692bd57c23ff31604c433124f8125af9 Mon Sep 17 00:00:00 2001 From: Noah Sloan Date: Tue, 8 Dec 2009 14:21:05 -0600 Subject: [PATCH 2/6] cache wrapper methods --- underscore.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/underscore.js b/underscore.js index b94cc0f9b..81898d4af 100644 --- a/underscore.js +++ b/underscore.js @@ -555,24 +555,28 @@ // Add all of the Underscore functions to the wrapper object. _.each(_.functions(_), function(name) { + var unshift = Array.prototype.unshift, + method = _[name]; wrapper.prototype[name] = function() { - Array.prototype.unshift.call(arguments, this._wrapped); - return result(_[name].apply(_, arguments), this._chain); + unshift.call(arguments, this._wrapped); + return result(method.apply(_, arguments), this._chain); }; }); // Add all mutator Array functions to the wrapper. _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = Array.prototype[name]; wrapper.prototype[name] = function() { - Array.prototype[name].apply(this._wrapped, arguments); + method.apply(this._wrapped, arguments); return result(this._wrapped, this._chain); }; }); // Add all accessor Array functions to the wrapper. _.each(['concat', 'join', 'slice'], function(name) { + var method = Array.prototype[name]; wrapper.prototype[name] = function() { - return result(Array.prototype[name].apply(this._wrapped, arguments), this._chain); + return result(method.apply(this._wrapped, arguments), this._chain); }; }); From a5454d6972063a65bfa0611a237663f19e509856 Mon Sep 17 00:00:00 2001 From: Noah Sloan Date: Tue, 8 Dec 2009 14:24:44 -0600 Subject: [PATCH 3/6] cache hasOwnProperty --- underscore.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/underscore.js b/underscore.js index 81898d4af..da40afaa8 100644 --- a/underscore.js +++ b/underscore.js @@ -391,10 +391,11 @@ /* ------------------------- Object Functions: ---------------------------- */ // Retrieve the names of an object's properties. + var hasOwnProperty = Object.prototype.hasOwnProperty; _.keys = function(obj) { if(_.isArray(obj)) return _.range(0, obj.length); var keys = []; - for (var key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) keys.push(key); + for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key); return keys; }; From 6554c6d9762d71c056d573fabf0ead967a75b308 Mon Sep 17 00:00:00 2001 From: Noah Sloan Date: Tue, 8 Dec 2009 15:57:04 -0600 Subject: [PATCH 4/6] have to define isNumber before _.each will work in IE --- underscore.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/underscore.js b/underscore.js index da40afaa8..834ecac9a 100644 --- a/underscore.js +++ b/underscore.js @@ -475,10 +475,15 @@ _.isUndefined = function(obj) { return typeof obj == 'undefined'; }; + + // have to define isNumber before _.each will work in IE + _.isNumber = function(obj) { + return Object.prototype.toString == '[object Number]'; + }; - // Define the isArray, isDate, isFunction, isNumber, isRegExp, and + // Define the isArray, isDate, isFunction, isRegExp, and // isString functions based on their toString identifiers. - _.each(['Array', 'Date', 'Function', 'Number', 'RegExp', 'String'], function(type) { + _.each(['Array', 'Date', 'Function', 'RegExp', 'String'], function(type) { var toString = Object.prototype.toString, typeString = '[object ' + type + ']'; _['is' + type] = function(obj) { return toString.call(obj) == typeString; From 37930f92e0031bb0f5a591827ecef13863f19f9a Mon Sep 17 00:00:00 2001 From: Noah Sloan Date: Tue, 8 Dec 2009 16:03:53 -0600 Subject: [PATCH 5/6] doh. messed up isNumber fix --- underscore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/underscore.js b/underscore.js index 834ecac9a..017018790 100644 --- a/underscore.js +++ b/underscore.js @@ -478,7 +478,7 @@ // have to define isNumber before _.each will work in IE _.isNumber = function(obj) { - return Object.prototype.toString == '[object Number]'; + return Object.prototype.toString.call(obj) == '[object Number]'; }; // Define the isArray, isDate, isFunction, isRegExp, and From 76cccb6a2dc58b71811e4cc4ce5733a2b11e959f Mon Sep 17 00:00:00 2001 From: Noah Sloan Date: Wed, 9 Dec 2009 10:00:48 -0600 Subject: [PATCH 6/6] added JSLitmus tests for isType functions --- test/speed.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/speed.js b/test/speed.js index 86663a237..50fd3dc60 100644 --- a/test/speed.js +++ b/test/speed.js @@ -5,6 +5,31 @@ var objects = _.map(numbers, function(n){ return {num : n}; }); var randomized = _.sortBy(numbers, function(){ return Math.random(); }); + JSLitmus.test('_.isNumber()', function() { + _.isNumber(123); + _.isNumber(null); + _.isNumber(NaN); + _.isNumber(/foo/); + _.isNumber("abc"); + }); + + JSLitmus.test('_.isString()', function() { + _.isString(123); + _.isString(null); + _.isString(NaN); + _.isString(/foo/); + _.isString("abc"); + }); + + JSLitmus.test('_.isDate()', function() { + _.isDate(123); + _.isDate(null); + _.isDate(NaN); + _.isDate(/foo/); + _.isDate("abc"); + _.isDate(new Date()); + }); + JSLitmus.test('_.each()', function() { var timesTwo = []; _.each(numbers, function(num){ timesTwo.push(num * 2); });