Skip to content

Commit 9c4f9da

Browse files
Dave MacLachlanmobile-devx-github-bot
authored andcommitted
Cache method signatures in EDOObject.
This change introduces a thread-safe cache within `EDOObject` to store method signatures. When `methodSignatureForSelector:` is called, it first checks the cache. If the signature is not found, a remote request is made, and the result is then added to the cache for future use. This reduces redundant remote calls for method signature lookups. This should improve overall edo performance. PiperOrigin-RevId: 822643324
1 parent 2993123 commit 9c4f9da

1 file changed

Lines changed: 58 additions & 3 deletions

File tree

Service/Sources/EDOObject+Invocation.m

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#import "Service/Sources/EDOParameter.h"
3030
#import "Service/Sources/EDORemoteException.h"
3131
#import "Service/Sources/EDOServicePort.h"
32+
#import "Service/Sources/EDOServiceRequest.h"
3233

3334
static EDORemoteException *RemoteExceptionWithLocalInformation(EDORemoteException *remoteException,
3435
EDOObject *target,
@@ -66,6 +67,46 @@
6667
callStackSymbols:fullStackTraces];
6768
}
6869

70+
// The cache of the instance method signatures.
71+
static NSCache<NSString *, NSMethodSignature *> *gEDOInstanceMethodSignatureCache;
72+
73+
/**
74+
* Builds the key for the instance method signature cache.
75+
*
76+
* @param selector The selector.
77+
* @param className The class name.
78+
* @return The key.
79+
*/
80+
static NSString *EDOCreateMethodSignatureCacheKey(SEL selector, NSString *className) {
81+
return [NSString stringWithFormat:@"%@-%@", className, NSStringFromSelector(selector)];
82+
}
83+
84+
/**
85+
* Gets the instance method signature for the given selector and class name from the cache.
86+
*
87+
* @param selector The selector.
88+
* @param className The class name.
89+
* @return The instance method signature.
90+
*/
91+
static NSMethodSignature *EDOInstanceMethodSignatureForSelector(SEL selector, NSString *className) {
92+
NSString *key = EDOCreateMethodSignatureCacheKey(selector, className);
93+
NSMethodSignature *methodSignature = [gEDOInstanceMethodSignatureCache objectForKey:key];
94+
return methodSignature;
95+
}
96+
97+
/**
98+
* Adds the instance method signature for the given selector and class name to the cache.
99+
*
100+
* @param methodSignature The method signature.
101+
* @param selector The selector.
102+
* @param className The class name.
103+
*/
104+
static void EDOAddInstanceMethodSignature(NSMethodSignature *methodSignature, SEL selector,
105+
NSString *className) {
106+
NSString *key = EDOCreateMethodSignatureCacheKey(selector, className);
107+
[gEDOInstanceMethodSignatureCache setObject:methodSignature forKey:key];
108+
}
109+
69110
/**
70111
* The extension of EDOObject to handle the message forwarding.
71112
*
@@ -81,6 +122,12 @@
81122
*/
82123
@implementation EDOObject (Invocation)
83124

125+
+ (void)initialize {
126+
if (self == [EDOObject class]) {
127+
gEDOInstanceMethodSignatureCache = [[NSCache alloc] init];
128+
}
129+
}
130+
84131
/**
85132
* Get an instance method signature for the @c EDOObject
86133
*
@@ -91,15 +138,23 @@ @implementation EDOObject (Invocation)
91138
* @return The instance method signature.
92139
*/
93140
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
94-
// TODO(haowoo): Cache the signature.
141+
NSString *className = self.className;
142+
NSMethodSignature *signature = EDOInstanceMethodSignatureForSelector(selector, className);
143+
if (signature) {
144+
return signature;
145+
}
95146
EDOServiceRequest *request = [EDOMethodSignatureRequest requestWithObject:self.remoteAddress
96147
port:self.servicePort
97148
selector:selector];
98149
EDOMethodSignatureResponse *response = (EDOMethodSignatureResponse *)[EDOClientService
99150
sendSynchronousRequest:request
100151
onPort:self.servicePort.hostPort];
101-
NSString *signature = response.signature;
102-
return signature ? [NSMethodSignature signatureWithObjCTypes:signature.UTF8String] : nil;
152+
NSString *signatureString = response.signature;
153+
if (signatureString) {
154+
signature = [NSMethodSignature signatureWithObjCTypes:signatureString.UTF8String];
155+
EDOAddInstanceMethodSignature(signature, selector, className);
156+
}
157+
return signature;
103158
}
104159

105160
/** Forwards the invocation to the remote. */

0 commit comments

Comments
 (0)