Archive for September, 2005

C: Power of 2 Array Sizes

Sunday, September 18th, 2005

I just picked up a 10-year old copy of O’Reilly’s Practical C, 3rd Edition from the library for some light reading. Mostly, I just wanted to see if I would learn anything (as a guage of my own C proficiency). I’m glad to announce that I learned almost nothing, until, that is, I read page 258, The Power of Powers of 2.

This page is in the section on optimization. Before I go further, I must say that I agree with the author, that when it comes to code optimization: don’t. With that aside, let’s proceed.

I have seen a lot of C arrays declared and allocated with a power-of-2 size (like 256):

int *values = (int*)malloc(256);

And I never really knew why coders used sizes of 256, instead of 200 or some other more “comfortable” number. I figured that it did something to make the code “better”, but I didn’t know exactly what. Today, I found the answer. Most C compilers will optimize this:

x = x * 8;

Into this:

x = x < < 3;

The left shift operation requires fewer cycles than the multiply operation, so malloc() can get its job done faster when calculating how many bytes to allocate.

The fact is also true for accessing elements of multi-dimensional arrays. Take, for example, the following matrix:

int matrix[256][256]

When accesing an element in this matrix array, say element (12,39), the compiler has to do the following computations:

base_address + 12 * 256 * sizeof(int) + 39 * sizeof(int)

The 12 * 256 can be optimized to 12 << 8, making each array access a tiny bit faster. In code where this is happening a lot, it may even make a difference.

I guess this also explains why there is no 3-byte integer type, while there are 2-byte and 4-byte integers. And there will likely never be a 6-byte integer either.

Anyway, when it comes to optimization, there is so much voodoo and black magic in play that it’s really hard to know what provides the most bang for its buck. I might not even be right on this account either. Please correct me if you know better.

Qt: Connecting signals to … signals

Friday, September 16th, 2005

I found out today that Qt’s slots/signals architecture is even better than I thought. Normally, developers connect widget signals to widget slots to be notified of events. Today I discovered that signals can actually be connected to other signals, which saved me from writing some really stupid code…

This may seem weird, but consider this scenario. You have a custom widget, called MyWidget, that has a signal, somethingClicked(), which is emitted when a user clicks, uh, something. But now you want to add a QPopupMenu as a right-click context menu, that causes the somethingClicked() signal to be emitted also. It turns out there’s a hard way and an easy way to do this.

First, the hard way:

1. Add a new slot called emitSomethingClickedSlot() that looks like this:

MyWidget::emitSomethingClickedSlot() {
        emit somethingClicked();
}

2. Then, connect the QPopupMenu‘s menu item to this slot, like so:

popupMenu->insertItem( "Click me", this,
     SLOT(emitSomethingClickedSlot()) );

That sucks. We just created a slot whose sole purpose is to turn around and emit a signal. What a waste of editor space. It would have been smarter to connect the menu item’s signal directly to the somethingClicked() signal.

Here’s the easy way:

popupMenu->insertItem( "Click me", this,
     SIGNAL(somethingClicked()) );

Now that’s concise. Sometimes it pays to connect signals to signals.