mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
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:
parent
c80250ed90
commit
e0ecf75559
7 changed files with 67 additions and 38 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -92,7 +92,7 @@ typedef struct {
|
|||
* String implementations.
|
||||
*/
|
||||
unsigned (*_NSString_hash)();
|
||||
unsigned (*_NSGString_hash)();
|
||||
BOOL (*_NSString_isEqualToString_)();
|
||||
BOOL (*_NSGString_isEqual_)();
|
||||
BOOL (*_NSGCString_isEqual_)();
|
||||
} fastImp;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue