diff --git a/src/core.js b/src/core.js
index 53d5f4a4..30820bf9 100644
--- a/src/core.js
+++ b/src/core.js
@@ -342,15 +342,14 @@ jQuery.fn = jQuery.prototype = {
},
not: function( selector ) {
- return this.pushStack(
- selector.constructor == String &&
- jQuery.multiFilter( selector, this, true ) ||
+ if (selector.constructor == String)
+ // test special case where just one selector is passed in
+ if ( /^.[^:#\[\.]*$/.test(selector) )
+ return this.pushStack( jQuery.multiFilter( selector, this, true ) );
+ else
+ selector = jQuery.multiFilter( selector, this );
- jQuery.grep(this, function(elem) {
- return selector.constructor == Array || selector.jquery ?
- jQuery.inArray( elem, selector ) < 0 :
- elem != selector;
- }) );
+ return this.pushStack( jQuery.removeFromArray( selector, this ) );
},
add: function( selector ) {
@@ -1093,6 +1092,13 @@ jQuery.extend({
return -1;
},
+ removeFromArray: function( remove, from ) {
+ var isArrayLike = remove.length && remove[remove.length - 1] !== undefined;
+ return jQuery.grep(from, function(elem) {
+ return isArrayLike ? jQuery.inArray( elem, remove ) < 0 : elem != from;
+ });
+ },
+
merge: function( first, second ) {
// We have to loop this way because IE & Opera overwrite the length
// expando of getElementsByTagName
diff --git a/src/selector.js b/src/selector.js
index c35fbb1e..6e916a2e 100644
--- a/src/selector.js
+++ b/src/selector.js
@@ -320,7 +320,11 @@ jQuery.extend({
// :not() is a special case that can be optimized by
// keeping it out of the expression list
if ( m[1] == ":" && m[2] == "not" )
- r = jQuery.filter(m[3], r, true).r;
+ // optimize if only one selector found (most common case)
+ if ( /^.[^:#\[\.]*$/.test(m[3]) )
+ r = jQuery.filter(m[3], r, true).r;
+ else
+ r = jQuery.removeFromArray(jQuery.multiFilter(m[3], r), r);
// We can get a big speed boost by filtering by class here
else if ( m[1] == "." )
diff --git a/test/index.html b/test/index.html
index cdd6a30b..b062179f 100644
--- a/test/index.html
+++ b/test/index.html
@@ -61,19 +61,19 @@