[haiku-appserver] Re: [Haiku-commits] r14599 - haiku/trunk/src/servers/app

  • From: Ingo Weinhold <bonefish@xxxxxxxxxxxxxxx>
  • To: haiku-appserver@xxxxxxxxxxxxx
  • Date: Tue, 01 Nov 2005 01:48:25 +0100

On 2005-11-01 at 00:02:58 [+0100], Adi Oanca wrote:
> Ingo Weinhold wrote:
> > On 2005-10-31 at 21:50:20 [+0100], Adi Oanca wrote:
[...]
> >>    To avoid a few CPU cycles please pull out local declarations from 
> >>    loops.
> > 
> > Please don't do something like this; keeping variables as local as 
> > possible
> > increases the readability. Furthermore trust the compiler. Don't try to 
> > trick
> > it -- it's your friend. Extending the scope of a variable may cause a 
> > bigger
> > stack footprint and may even make your code slower, since the compiler has
> > less knowledge it can apply.
> 
>     Umm... I don't think so. At least my tests and the books I read point
> this as a very simple method of optimizing code.

Regarding books about this kind of optimization, one can usually throw them 
away when the next compiler version is released. Regarding tests, I couldn't 
help it and compiled these two (nonsense) functions:

static void
test1(const char *longString)
{
        for (int i = 0; i < 1000; i++) {
                const char *str = longString + i;
                printf("pos: %d\n", str - longString);
        }
}

static void
test1(const char *longString)
{
        const char *str;
        for (int i = 0; i < 1000; i++) {
                str = longString + i;
                printf("pos: %d\n", str - longString);
        }
}

Compiling without optimization results in different assembler code. Just as 
suspected. Unlike you suggest, there is no more overhead involved in the 
first version.

On x86 local variables are referenced relative to the stack frame pointer 
(ebp). Declaring a local variable does not result in actual code, it only 
causes the compiler to reserve space for the variable while compiling. In the 
first version, the compiler reserves the four bytes at -4(epb) for i and the 
four bytes at -8(ebp) for str. In the second version things are just 
reversed. No effect on performance.

When compiling with optimization (-O2) the compiler even spits out the same 
assembler code.

>     (readability is down with 5% - not even noticeable)

Do that twenty times and you have -100%. ;-)
Seriously, readability is paramount especially in an open source project, 
where the original author might not maintain the code forever.

>     (the stack footprint ain't bigger at all. one variable put on stack
> once VS. the same variable pushed an pop-ed many times)

If you invoke a function after the loop in the above functions, the space 
reserved for str can be reused in the first case, while it has to be 
preserved in the second, since the lifetime of str is not over at that point. 
If that imaginary function is stack-critical, you'll have 4 byte less of 
stack space for it.

>     Also, this code:
>  >>>+            while (fDesktops.CountItems() > 0) {
>  >>>+                Desktop *desktop = fDesktops.RemoveItemAt(0);
>     is not optimal at all.
>     I'm not saying we should optimize at this stage, but you know, you were
> the one who said that simple optimizations should find their way at the
> time the code is written.

I was referring only to the "pulling variable declarations out of loops" 
statement. Personally I wouldn't write a code fragment like this, even, as 
Axel says, if there are only a few elements in fDesktops.

CU, Ingo

Other related posts: