From 4be6a194cdc039c7a1cbcef8812027289f997b20 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Fri, 1 Jan 2010 19:05:34 -0500 Subject: [PATCH] replacing all isType tests that relied on string comparisons with versions that check for existence of known methods and properties. Less safe, but more than an order of magnitude faster. --- test/temp.js | 25 ++++++++++++++++++++ test/temp_tests.html | 19 ++++++++++++++++ underscore.js | 54 ++++++++++++++++++++++++++++++-------------- 3 files changed, 81 insertions(+), 17 deletions(-) create mode 100644 test/temp.js create mode 100644 test/temp_tests.html diff --git a/test/temp.js b/test/temp.js new file mode 100644 index 000000000..657807239 --- /dev/null +++ b/test/temp.js @@ -0,0 +1,25 @@ +(function() { + + var func = function(){}; + var date = new Date(); + var str = "a string"; + var numbers = []; + for (var i=0; i<1000; i++) numbers.push(i); + var objects = _.map(numbers, function(n){ return {num : n}; }); + var randomized = _.sortBy(numbers, function(){ return Math.random(); }); + + JSLitmus.test('_.each()', function() { + var timesTwo = []; + _.each(numbers, function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('_.isString', function() { + return _.isString(str); + }); + + JSLitmus.test('_.isStringNew', function() { + return _.isStringNew(str); + }); + +})(); \ No newline at end of file diff --git a/test/temp_tests.html b/test/temp_tests.html new file mode 100644 index 000000000..bd34f9dd7 --- /dev/null +++ b/test/temp_tests.html @@ -0,0 +1,19 @@ + + + + Underscore Temporary Tests + + + + + + + +

Underscore Temporary Tests

+

+ A page for temporary speed tests, used for developing faster implementations + of existing Underscore methods. +

+
+ + diff --git a/underscore.js b/underscore.js index 8a6d9e0c5..d986c6543 100644 --- a/underscore.js +++ b/underscore.js @@ -428,6 +428,13 @@ return _.extend({}, obj); }; + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + // Perform a deep comparison to check if two objects are equal. _.isEqual = function(a, b) { // Check object identity. @@ -474,11 +481,41 @@ return !!(obj && obj.nodeType == 1); }; + // Is a given value an array? + _.isArray = function(obj) { + return obj && obj.concat && obj.unshift; + }; + // Is a given variable an arguments object? _.isArguments = function(obj) { return obj && _.isNumber(obj.length) && !_.isArray(obj) && !propertyIsEnumerable.call(obj, 'length'); }; + // Is a given value a function? + _.isFunction = function(obj) { + return obj && obj.constructor && obj.call && obj.apply; + }; + + // Is a given value a string? + _.isString = function(obj) { + return obj === '' || (obj && obj.charCodeAt && obj.substr); + }; + + // Is a given value a number? + _.isNumber = function(obj) { + return toString.call(obj) === '[object Number]'; + }; + + // Is a given value a date? + _.isDate = function(obj) { + return obj && obj.getTimezoneOffset && obj.setUTCFullYear; + }; + + // Is the given value a regular expression? + _.isRegExp = function(obj) { + return obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false); + }; + // Is the given value NaN -- this one is interesting. NaN != NaN, and // isNaN(undefined) == true, so we make sure it's a number first. _.isNaN = function(obj) { @@ -495,23 +532,6 @@ return typeof obj == 'undefined'; }; - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - } - - // Define the isArray, isDate, isFunction, isNumber, isRegExp, and isString - // functions based on their toString identifiers. - var types = ['Array', 'Date', 'Function', 'Number', 'RegExp', 'String']; - for (var i=0, l=types.length; i