Use local variables to avoid redundant method calls

 
Post new topic   Reply to topic    Mulle kybernetiK Optimization Forum Index :: Foundation & Objective-C
View previous topic :: View next topic  
Author Message
Nat!



Joined: 06 Aug 2004
Posts: 42
Location: Bochum

PostPosted: Tue Sep 07, 2004 10:17 pm    Post subject: Use local variables to avoid redundant method calls Reply with quote

This is a pet peeve of mine. I often see code, where methods, most often accessors, are called repeatedly within the same method, although the result is invariant. I am not quite sure, if that is because of a bad functional programming habit Twisted Evil, a false hope that the compiler will optimize it away Rolling Eyes , or just laziness Cool.

The truth is, the compiler can't optimize it away. This
Code:

static unsigned int   foo( NSString *s)
{
   return( [s length] + [s length] + [s length]);
}



compiles to 100 bytes (and as long as nothing major changes in Objective-C this will always compile into three method calls)
Quote:

_foo:
000043fc mfspr r0,lr
00004400 bcl 20,31,0x4404
00004404 stmw r27,0xffec(r1)
00004408 mfspr r31,lr
0000440c stw r0,0x8(r1)
00004410 or r27,r3,r3
00004414 addis r29,r31,0x0
00004418 stwu r1,0xffa0(r1)
0000441c addi r29,r29,0x1c08
00004420 lwz r4,0x0(r29)
00004424 bl 0x467c
00004428 lwz r4,0x0(r29)
0000442c or r28,r3,r3
00004430 or r3,r27,r27
00004434 bl 0x467c
00004438 lwz r4,0x0(r29)
0000443c add r28,r28,r3
00004440 or r3,r27,r27
00004444 bl 0x467c
00004448 lwz r0,0x68(r1)
0000444c addi r1,r1,0x60
00004450 add r3,r28,r3
00004454 lmw r27,0xffec(r1)
00004458 mtspr lr,r0
0000445c blr


but

Code:
static unsigned int   bar( NSString *s)
{
   unsigned int   len;
   
   len = [s length];
   return( len + len + len);
}


compiles to only 64 bytes

Quote:
_bar:
00004460 mfspr r0,lr
00004464 stw r31,0xfffc(r1)
00004468 bcl 20,31,0x446c
0000446c stw r0,0x8(r1)
00004470 mfspr r31,lr
00004474 stwu r1,0xffb0(r1)
00004478 addis r4,r31,0x0
0000447c lwz r4,0x1ba0(r4)
00004480 bl 0x467c
00004484 rlwinm r0,r3,1,0,30
00004488 add r3,r0,r3
0000448c lwz r0,0x58(r1)
00004490 addi r1,r1,0x50
00004494 lwz r31,0xfffc(r1)
00004498 mtspr lr,r0
0000449c blr


not only is bar (in my opinion) better style and more readable. It is also faster because the invariant result of the method call is cached and you saved two method calls. Now smaller code size makes for faster programs, because of better cache usage and smaller VM working sets. So you gain even more.

Using local variables as a habit can reduce code size appreciably.
Back to top
View user's profile Send private message Visit poster's website
GrosJambon



Joined: 09 Sep 2004
Posts: 1
Location: Paris

PostPosted: Thu Sep 09, 2004 2:13 pm    Post subject: Reply with quote

Hum, I've seen worse in some Apple source code.

[...]

if (something==false)
{
// deallocate a lot of stuff

[...]

return false;
}

// deallocate the very same lot of stuff

[...]

return true;
}
Back to top
View user's profile Send private message
whitenoise



Joined: 07 Sep 2004
Posts: 5

PostPosted: Thu Sep 09, 2004 5:03 pm    Post subject: Reply with quote

It's not a functional programming thing, it's because it's often faster and easier to write the code that way (usually via copy/paste), even though what you say is true: it's both more elegant (results in more readable code) and faster to execute using the cached variable value.

Thing is, I have a zillion things to do, I often have to get this particular code out immediately, and I can (and usually do) come back and clean up such code later when I have time. And usually the code isn't time-critical.

That's the rationale, at least for the experienced programmer who should otherwise know better. It's not a very good one, but it does save time to write code this way, especially if you're maintaining somebody else's lousy code with huge, bloated functions and you'd have to scroll the document to create the variable.

Novices may actually not realize the performance impact of multiple method or function calls. Even in C or C++ such code is more expensive than it needs to be.

The multiple deallocations thing I won't defend, because it's a major correctness issue. Multiple points of deallocation are doomed to get out of sync over time. There needs to be one point of deallocation.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Mulle kybernetiK Optimization Forum Index :: Foundation & Objective-C All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum




Powered by phpBB © 2001, 2002 phpBB Group
Charcoal2 Theme © Zarron Media