Search code examples
objective-cperformancesqrt

Why is Objective-C sqrtf() function faster than a function that just returns a value?


I have these functions in Objective-C:

-(void)emptyFunction
{
    NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate];

    float b;
    for (int i=0; i<1000000; i++) {
        b = [self returnNr:i];
    }

    NSTimeInterval endTime = [[NSDate date] timeIntervalSinceReferenceDate];

    double elapsedTime = endTime - startTime;
    NSLog(@"1. %f", elapsedTime);
}

-(float)returnNr:(float)number
{
    return number;
}

and

-(void)sqrtFunction
{
    NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate];

    float b;
    for (int i=0; i<1000000; i++) {
        b = sqrtf(i);
    }

    NSTimeInterval endTime = [[NSDate date] timeIntervalSinceReferenceDate];

    double elapsedTime = endTime - startTime;
    NSLog(@"2. %f", elapsedTime);
}

When I call them, in any order, it prints in console the following:

2014-01-13 12:23:00.458 RapidTest[443:70b] 1. 0.011970
2014-01-13 12:23:00.446 RapidTest[443:70b] 2. 0.006308

How is this happening? How can sqrtf() function be twice as faster than a function that just returns a value? I know sqrtf() works on bits with assembly language and such, but faster than just a return? How is it possible?


Solution

  • Calling [self returnNr:i] is not the same as simply calling a C function. Instead you're sending a message to self, which gets translated to the equivalent in C:

    objc_msgSend(self, @selector(returnNr:), i);
    

    This will eventually call your returnNr: implementation, but there's some overhead involved. For more details on what's going on in objc_msgSend see objc_msgSend tour or Let's build objc_msgSend

    [edit] Also see An Illustrated History of objc_msgSend, which shows how the implementation changed over time. Executing the code from your Q will have resulted in different results on different platform versions because of improvements / trade-offs made during the evolution of objc_msgSend.