Refactored for Efficiency

Refactoring your code is for more then keeping it DRY. It also gives you a chance to make it more efficient.

Take a look at the following Objective-C. Its goal is to return the full path to a sessions folder which is a subdirectory in the users documents directory.

-(NSString *)filePath {
    NSString *baseDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *sessionPath = [baseDirectory stringByAppendingPathComponent:self.sessionName];
    return [sessionPath stringByAppendingPathComponent:self.fileName];   
}

It accomplishes its task but is relatively expensive. There are two string concatenations, each of which involve another allocation of memory.

We can speed this up a bit by rewritting it like this:

-(NSString *)filePath {
    return [NSString stringWithFormat:@"%@/%@/%@",
         [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0], 
         self.sessionName, 
         self.fileName
    ]; 
}

The new method causes only one memory allocation and one string concatenation. Thats half of what our first attempt required.

We can also cache the result as it doesn’t change during its session. We simply add a NSString \*\_filePath to the containing class and refactor further.

-(NSString *)filePath {
    if(_filePath == null) {   
        _filePath = [NSString stringWithFormat:@"%@/%@/%@",
             [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0], 
             self.sessionName, 
             self.fileName
        ]; 
    }
    return _filePath;
}

The end result is a method that is twice is fast the first time it is called and even more so each additional call due to memoization.

tim@collectiveidea.com

Comments