From b62db0e294ab8d6d1869365e2207761e37516b7f Mon Sep 17 00:00:00 2001 From: theraven Date: Thu, 2 Sep 2010 15:17:46 +0000 Subject: [PATCH] Improve the efficiency of NSObject's methodSignatureForSelector by: - Moving the linear search over all of the method lists in the class hierarchy to the end. If we found the type info in the protocol list, we were throwing this info away. Doing something expensive and then discarding the result is generally not a good idea. - Replacing the linear search of the method lists with a dtable lookup on libobjc2. The type info for methods is part of the slot, so we only need to do the expensive search at all on the old runtime. With libobjc2, type info lookup costs as little as IMP lookup, so doing things the slow way is not required. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31231 72102866-910b-0410-8b05-ffd578937521 --- Source/NSObject.m | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Source/NSObject.m b/Source/NSObject.m index f79ec6d10..bcdd26d16 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -1465,8 +1465,7 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak)); */ - (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector { - const char *types; - struct objc_method *mth; + const char *types = NULL; Class c; if (0 == aSelector) @@ -1475,14 +1474,14 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak)); } c = (GSObjCIsInstance(self) ? object_getClass(self) : (Class)self); - mth = GSGetMethod(c, aSelector, GSObjCIsInstance(self), YES); - if (mth == 0) + // Do a fast lookup to see if the method is implemented at all. If it isn't, + // we can give up without doing a very expensive linear search through every + // method list in the class hierarchy. + if (!class_respondsToSelector(c, aSelector)) { return nil; // Method not implemented } - types = mth->method_types; - /* * If there are protocols that this class conforms to, * the method may be listed in a protocol with more @@ -1526,6 +1525,19 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak)); } } + if (types == 0) + { +#ifdef __GNUSTEP_RUNTIME__ + struct objc_slot* objc_get_slot(Class cls, SEL selector); + struct objc_slot *slot = objc_get_slot(c, aSelector); + types = slot->types; +#else + struct objc_method *mth = + GSGetMethod(c, aSelector, GSObjCIsInstance(self), YES); + types = mth->method_types; +#endif + } + if (types == 0) { return nil;