Optimise test for dictionary equality

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@15973 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2003-02-16 11:31:28 +00:00
parent bfed503388
commit 64d7feafd2
4 changed files with 93 additions and 2 deletions

View file

@ -1,3 +1,10 @@
2003-02-16 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSDictionary.m: ([-isEqualToDictionary:]) implement optimised
version which does not need to create a key enumerator.
* Source/GSArray.m: ditto
* Source/GSSet.m: similar minor optimisations.
2003-02-15 15:53 Alexander Malmberg <alexander@malmberg.org>
* Source/NSRunLoop.m (-performSelector:target:argument:order:modes:):

View file

@ -33,6 +33,7 @@
#include <Foundation/NSDebug.h>
static SEL eqSel;
static SEL oaiSel;
static Class GSInlineArrayClass;
@ -75,6 +76,7 @@ static Class GSInlineArrayClass;
{
[self setVersion: 1];
eqSel = @selector(isEqual:);
oaiSel = @selector(objectAtIndex:);
GSInlineArrayClass = [GSInlineArray class];
}
}
@ -226,6 +228,33 @@ static Class GSInlineArrayClass;
return NSNotFound;
}
- (BOOL) isEqualToArray: (NSArray*)otherArray
{
unsigned i;
if (self == (id)otherArray)
{
return YES;
}
if (_count != [otherArray count])
{
return NO;
}
if (_count > 0)
{
IMP get1 = [otherArray methodForSelector: oaiSel];
for (i = 0; i < _count; i++)
{
if (![_contents_array[i] isEqual: (*get1)(otherArray, oaiSel, i)])
{
return NO;
}
}
}
return YES;
}
- (id) lastObject
{
if (_count)

View file

@ -244,6 +244,42 @@ static SEL objSel;
return self;
}
- (BOOL) isEqualToDictionary: (NSDictionary*)other
{
unsigned count;
if (other == self)
{
return YES;
}
count = map.nodeCount;
if (count == [other count])
{
if (count > 0)
{
GSIMapEnumerator_t enumerator;
GSIMapNode node;
IMP otherObj = [other methodForSelector: objSel];
enumerator = GSIMapEnumeratorForMap(&map);
while ((node = GSIMapEnumeratorNextNode(&enumerator)) != 0)
{
id o1 = node->value.obj;
id o2 = (*otherObj)(other, objSel, node->key.obj);
if (o1 != o2 && [o1 isEqual: o2] == NO)
{
GSIMapEndEnumerator(&enumerator);
return NO;
}
}
GSIMapEndEnumerator(&enumerator);
}
return YES;
}
return NO;
}
- (NSEnumerator*) keyEnumerator
{
return AUTORELEASE([[GSDictionaryKeyEnumerator allocWithZone:

View file

@ -39,6 +39,8 @@
#include <base/GSIMap.h>
static SEL memberSel;
@interface GSSet : NSSet
{
@public
@ -107,6 +109,7 @@ static Class mutableSetClass;
arrayClass = [NSArray class];
setClass = [GSSet class];
mutableSetClass = [GSMutableSet class];
memberSel = @selector(member:);
}
}
@ -283,13 +286,19 @@ static Class mutableSetClass;
{
GSIMapEnumerator_t enumerator;
GSIMapNode node;
IMP imp;
// -1. members of this set(self) <= that of otherSet
if (map.nodeCount > [otherSet count])
{
return NO;
}
if (map.nodeCount == 0)
{
return YES;
}
imp = [otherSet methodForSelector: memberSel];
enumerator = GSIMapEnumeratorForMap(&map);
node = GSIMapEnumeratorNextNode(&enumerator);
@ -297,7 +306,7 @@ static Class mutableSetClass;
while (node != 0)
{
// 1. check the member is in the otherSet.
if ([otherSet member: node->key.obj])
if ((*imp)(otherSet, memberSel, node->key.obj) != nil)
{
// 1.1 if true -> continue, try to check the next member.
node = GSIMapEnumeratorNextNode(&enumerator);
@ -334,6 +343,10 @@ static Class mutableSetClass;
{
return NO;
}
else if (map.nodeCount == 0)
{
return YES;
}
else
{
GSIMapEnumerator_t enumerator;
@ -360,17 +373,23 @@ static Class mutableSetClass;
{
return NO;
}
else if (map.nodeCount == 0)
{
return YES;
}
else
{
GSIMapEnumerator_t enumerator;
GSIMapNode node;
IMP imp;
imp = [other methodForSelector: memberSel];
enumerator = GSIMapEnumeratorForMap(&map);
node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
if ([other member: node->key.obj] == nil)
if ((*imp)(other, memberSel, node->key.obj) == nil)
{
GSIMapEndEnumerator(&enumerator);
return NO;