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?
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
.