Some final tiny optimisations for testing string equality.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3045 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1998-10-09 04:24:56 +00:00
parent c80250ed90
commit e0ecf75559
7 changed files with 67 additions and 38 deletions

View file

@ -27,8 +27,12 @@
#include <gnustep/base/preface.h>
#include <Foundation/NSString.h>
/* NSGCString and NSGMutableCString must have the same initial ivar layout
because of class_add_behavior() in NSGMutableCString's +initialize. */
/*
* NSGCString and NSGMutableCString must have the same initial ivar layout
* because of class_add_behavior() in NSGMutableCString's +initialize
* and because the various string classes (and NSGDictionary) examine and
* set each others _hash ivar directly for performance reasons!
*/
@interface NSGCString : NSString
{

View file

@ -92,7 +92,7 @@ typedef struct {
* String implementations.
*/
unsigned (*_NSString_hash)();
unsigned (*_NSGString_hash)();
BOOL (*_NSString_isEqualToString_)();
BOOL (*_NSGString_isEqual_)();
BOOL (*_NSGCString_isEqual_)();
} fastImp;

View file

@ -47,8 +47,7 @@
- (unsigned) hash
{
if (_hash == 0)
if ((_hash = _fastImp._NSString_hash(self, @selector(hash))) == 0)
_hash = 0xffffffff;
_hash = _fastImp._NSString_hash(self, @selector(hash));
return _hash;
}
@ -116,7 +115,6 @@
- initWithCoder: aCoder
{
[super initWithCoder:aCoder];
[aCoder decodeValueOfObjCType:@encode(char*) at:&_contents_chars
withName:NULL];
_count = strlen(_contents_chars);
@ -270,20 +268,22 @@
if (_count != other->_count)
return NO;
if (_hash == 0)
if ((_hash = _fastImp._NSString_hash(self, @selector(hash))) == 0)
_hash = 0xffffffff;
_hash = _fastImp._NSString_hash(self, @selector(hash));
if (other->_hash == 0)
_fastImp._NSGString_hash(other, @selector(hash));
other->_hash = _fastImp._NSString_hash(other, @selector(hash));
if (_hash != other->_hash)
return NO;
if (memcmp(_contents_chars, other->_contents_chars, _count) != 0)
return NO;
return YES;
}
else if ([c isKindOfClass: [NSString class]])
return [super isEqualToString: (NSString*)anObject];
else if (c == nil)
return NO;
else if (fastClassIsKindOfClass(c, _fastCls._NSString))
return _fastImp._NSString_isEqualToString_(self,
@selector(isEqualToString:), anObject);
else
return [super isEqual: anObject];
return NO;
}
- (BOOL) isEqualToString: (NSString*)aString
@ -302,18 +302,22 @@
if (_count != other->_count)
return NO;
if (_hash == 0)
if ((_hash = _fastImp._NSString_hash(self, @selector(hash))) == 0)
_hash = 0xffffffff;
_hash = _fastImp._NSString_hash(self, @selector(hash));
if (other->_hash == 0)
_fastImp._NSGString_hash(other, @selector(hash));
other->_hash = _fastImp._NSString_hash(other, @selector(hash));
if (_hash != other->_hash)
return NO;
if (memcmp(_contents_chars, other->_contents_chars, _count) != 0)
return NO;
return YES;
}
else if (c == nil)
return NO;
else if (fastClassIsKindOfClass(c, _fastCls._NSString))
return _fastImp._NSString_isEqualToString_(self,
@selector(isEqualToString:), aString);
else
return [super isEqualToString: aString];
return NO;
}

View file

@ -55,10 +55,11 @@ myHash(NSObject *obj)
c == _fastCls._NSGString ||
c == _fastCls._NSGMutableString) {
if (((dictAccessToStringHack)obj)->_hash != 0) {
return ((dictAccessToStringHack)obj)->_hash;
if (((dictAccessToStringHack)obj)->_hash == 0) {
((dictAccessToStringHack)obj)->_hash =
_fastImp._NSString_hash(obj, @selector(hash));
}
return _fastImp._NSGString_hash(obj, @selector(hash));
return ((dictAccessToStringHack)obj)->_hash;
}
}
return [obj hash];

View file

@ -57,8 +57,7 @@
- (unsigned) hash
{
if (_hash == 0)
if ((_hash = _fastImp._NSString_hash(self, @selector(hash))) == 0)
_hash = 0xffffffff;
_hash = _fastImp._NSString_hash(self, @selector(hash));
return _hash;
}
@ -70,20 +69,28 @@
if (anObject == nil)
return NO;
c = fastClassOfInstance(anObject);
if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString)
if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString ||
c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString ||
c == _fastCls._NXConstantString)
{
NSGString *other = (NSGString*)anObject;
if (_hash == 0)
_fastImp._NSGString_hash(self, @selector(hash));
_hash = _fastImp._NSString_hash(self, @selector(hash));
if (other->_hash == 0)
_fastImp._NSGString_hash(other, @selector(hash));
other->_hash = _fastImp._NSString_hash(other, @selector(hash));
if (_hash != other->_hash)
return NO;
return [self isEqualToString: other];
return _fastImp._NSString_isEqualToString_(self,
@selector(isEqualToString:), other);
}
else if (c == nil)
return NO;
else if (fastClassIsKindOfClass(c, _fastCls._NSString))
return _fastImp._NSString_isEqualToString_(self,
@selector(isEqualToString:), anObject);
else
return [super isEqual: anObject];
return NO;
}
// Initializing Newly Allocated Strings
@ -231,7 +238,6 @@
- (void) encodeWithCoder: aCoder
{
[super encodeWithCoder:aCoder]; // *** added this
[aCoder encodeValueOfObjCType:@encode(int) at:&_count
withName:@"Concrete String count"];
[aCoder encodeArrayOfObjCType:@encode(unichar)
@ -242,7 +248,6 @@
- initWithCoder: aCoder
{
[super initWithCoder:aCoder];
[aCoder decodeValueOfObjCType:@encode(int) at:&_count
withName:NULL];
OBJC_MALLOC(_contents_chars, unichar, _count+1);

View file

@ -47,19 +47,22 @@ void _fastBuildCache()
/*
* Cache some classes for quick access later.
*/
_fastCls._NSString = [NSString class];
_fastCls._NSGString = [NSGString class];
_fastCls._NSGMutableString = [NSGMutableString class];
_fastCls._NSGCString = [NSGCString class];
_fastCls._NSGMutableCString = [NSGMutableCString class];
_fastCls._NXConstantString = [NXConstantString class];
/*
* Cache some method implementations for quick access later.
*/
_fastImp._NSString_hash = (unsigned (*)())[_fastCls._NSString
instanceMethodForSelector: @selector(hash)];
_fastImp._NSGString_hash = (unsigned (*)())[_fastCls._NSGString
instanceMethodForSelector: @selector(hash)];
_fastImp._NSString_isEqualToString_ = (BOOL (*)())[_fastCls._NSString
instanceMethodForSelector: @selector(isEqualToString:)];
_fastImp._NSGString_isEqual_ = (BOOL (*)())[_fastCls._NSGString
instanceMethodForSelector: @selector(isEqual:)];
_fastImp._NSGCString_isEqual_ = (BOOL (*)())[_fastCls._NSGCString

View file

@ -66,6 +66,9 @@
#include <gnustep/base/NSGString.h>
#include <gnustep/base/NSGCString.h>
#include <gnustep/base/fast.x>
// Uncomment when implemented
static NSStringEncoding _availableEncodings[] = {
NSASCIIStringEncoding,
@ -1406,11 +1409,19 @@ else
- (BOOL) isEqual: (id)anObject
{
if (anObject == self)
return YES;
if ([anObject isKindOfClass:[NSString class]] == YES)
return [self isEqualToString:anObject];
return NO;
if (anObject == self) {
return YES;
}
if (anObject != nil) {
Class c = fastClassOfInstance(anObject);
if (c != nil) {
if (fastClassIsKindOfClass(c, _fastCls._NSString)) {
return [self isEqualToString: anObject];
}
}
}
return NO;
}
- (BOOL) isEqualToString: (NSString*)aString
@ -1572,7 +1583,7 @@ else
/*
* The hash caching in our concrete strin classes uses zero to denote
* an empty cache value, so we must not return a hash of zero.
* an empty cache value, so we MUST NOT return a hash of zero.
*/
if (ret == 0)
ret = 0xffffffff;
@ -2640,12 +2651,13 @@ else
- (void) encodeWithCoder: anEncoder
{
[super encodeWithCoder:anEncoder];
[self subclassResponsibility:_cmd];
}
- initWithCoder: aDecoder
{
return [super initWithCoder:aDecoder];
[self subclassResponsibility:_cmd];
return self;
}
@end