Delen via


The Risk of Micro-optimizations

A lot of things have been said over the years about premature optimization, and after running into the following bug I thought it served as a good example of a type of premature optimization that I call "micro-optimization". That is, doing something quirky in order to save a tiny amount of RAM or CPU cycles. More often than not these quirks lead to bugs and less maintainable code, with no actual performance increase.

The following bug was in a class in an application designed to run on a modern desktop, and there would only be a few instances alive at any one time (say, 1-10 typically, maybe 100 in edge cases), so the amount of memory saved was negligible (if any).

This is a rather easy "spot the bug" exercise so I won't give it away. ;-)

 DWORD WEATHER_SUNNY   = 0x0001;
DWORD WEATHER_RAINING = 0x0002;

struct CWeather
{
    BOOL _fRaining:1;

    CWeather(DWORD dwFlags)
    {
        _fRaining = (dwFlags & WEATHER_RAINING);
    }

    BOOL IsRaining()
    {
        return _fRaining;
    }
};

int main()
{
    CWeather weather(WEATHER_RAINING);

    if (weather.IsRaining())
    {
        cout << "It's raining!" << endl;
    }
    else
    {
        cout << "It's not raining!" << endl;
    }

    return 0;
}

Note: Depending on your compiler, if you crank up your warning level high enough you should get a warning for this. (Although curiously I didn't with VS 2005 and /W4).

Comments

  • Anonymous
    January 23, 2006
    The comment has been removed
  • Anonymous
    January 23, 2006
    The comment has been removed
  • Anonymous
    January 23, 2006
    BOOL IsRaining()
    {
    return _fRaining;
    }

    Returning uninitialized bits?
  • Anonymous
    January 24, 2006
    There's absolutely no point doing this since the compiler will not combine the single bits from multiple instances of the class. It will round up each instance to one whole byte. I don't think it will add any extra padding between instances, so an array of 10 CWeather objects will take 10 bytes (plus overhead), whereas they'd take 40 bytes if you used a BOOL. But unless that pushes you over a page boundary somewhere, it will have very little effect on your program.

    I don't have any quantitative analysis on how long 32-bit vs 8-bit operations on modern processors take, but the processor reads from main memory into cache in (IIRC) 64 byte chunks, at least for cacheable reads. Again, little benefit.
  • Anonymous
    June 08, 2009
    PingBack from http://quickdietsite.info/story.php?id=3657