Wednesday, July 23, 2008

When bitmasking, do as the ...

int flags = 830;
if ( flags & mask == mask ) { doSomething(); }

If you're reading the value of bits from a bit-wise flags variable, please don't acquire your mask like this:
int mask = Math.pow(2, p);

Especially if you're doing this for every row in a table...

Instead, do this:
int mask = 1 << p;

Yay, bit shifting. --Saved a few billion operations...

Actually, I should add, a lot of the time you need a mask that is r-wide with 1's, shifted m to the left.
Example (for r = 7, m = 9, 32 bit int): 00000000 00000000 11111110 00000000

To achieve this, there is a simple algorithm that is brilliantly efficient. (~ is NOT operation, << is left shift operation)

1: int mask = ~0;
2: mask = mask << r;
3: mask = ~mask;
4: mask = mask << m;

This works as follows: (--Assuming system zero-fills on shift left; this is typical.)
Example: (r = 5, m = 12, 32-bit int)

1: mask = 11111111 11111111 11111111 11111111
2: mask = 11111111 11111111 11111111 11100000
3: mask = 00000000 00000000 00000000 00011111
4: mask = 00000000 00000001 11110000 00000000

Voila. As you can see, this is a 5-wide bit mask shifted 12 bits. This is equivalent to the mask number: 2^17 - 2^12 = 131072 - 4096 = 126976.

So, have fun with that. Make your code more efficient. =)
(Also, It seems blogger.com doesn't play well with angle brackets... I had to create this post in HTML.)

Tuesday, July 22, 2008

We all lose things

We all lose things. It's only natural. You lose things the same way you lose thoughts, or your place in a book. It's a basic fact of life that we can't remember everything.

Some things, like birth certificates, and savings bonds, need to go somewhere safe; somewhere you can remember. Unfortunately, these types of things are usually the type that might remain somewhere for a really long time. They might stay there so long that you move on to new "safe" places. This is a little long winded, so I'll cut right to what I want to say.

I wonder if there is a way to make some sort of cataloguing system to help with this problem. It would have to be extremely quick and easy, and require minimum "fussing" to use. I'd love it if it could be automated, but that's just a fantasy. I'm thinking, at this stage, that it might not even be a full indexing system, specifying locations of objects, but something that allows you to record what floor of the house an object resides in, or perhaps what corner of the floor. It doesn't need to eliminate searching altogether; it should just reduce the search area from a daunting "three floors plus attic" to "living room".

Naturally, we have to decide whether the system will be a manual update system, or some sort of machine assisted search. I'm thinking about the latter, and there's a glint in my eye as I type this. I envision a loose network of nodes that transmit to a central hub which keeps track of the locations of objects. Objects could sleep and "wake" on intervals, (say every day, or every few hours --perhaps it could be set by a potentiometer) "pulsing" to notify the hub of it's location. Perhaps they could interact with "mini-hub" nodes (like wireless APs to a wireless network) to determine their "room". (closest mini-hub signal?)

Perhaps it would be possible to attach some sort of small adhesive strip that emits specific RF frequencies, where frequencies would be tied to a particular object.

But, I'm out of time for this brainstorming session. I like how it sounds so far...

Sweet circuit gear haul

It's often hard to find good Canadian retailers with competitive prices on the web. So, when I find one that sells great gear for a fair price, I feel compelled to spread the word. I just ordered a huge load of circuit gear from dipmicro.com, and let me tell you: for about $60 I got almost 300 pieces! Resistors, capacitors, transistors (light sensitive ones, too!), inductors, timers, jacks and adapter heads, LEDs, relays, rectifiers, regulators, and a 16x2 character blue LCD screen!

And, in 30 minutes I'm going to set off driving to Burlington to pick it up. It's not that the $12 it would cost to ship was excessive, I'm just excited to tinker.

As a quick side-note, I've been looking for LEDs for a while and, compared to other places, this is a steal. Radio Shack sells one red LED for $5.95! *roll eyes*

Monday, July 21, 2008

Optimization is still important

In today's world of OOP programmers, of graduates with lots of Java knowledge and very little theory of computer science, the focus is on code re-use, and the attitude is one that little code tweaks are not worth the effort. A professor of mine once lectured: "I don't want to know how the phone works, I just want to use it." Unfortunately, that attitude doesn't lead to sustainable business practice. In my opinion, to be a good programmer, you need to be a little nutty for optimization. It's not a coincidence that some of the best coders in the world are in algorithmics, and many have great mathematical backgrounds.

I recently had to pick up after someone who had bloated a web based tool until it took 19 seconds to just load the main view. This was running off an 8x Core2 Xeon 2.4GHz server with 16GB of ram and 4x 30GB 15K RPM SCSIs in RAID10!

To give an example, on a summary page, he was re-using a function, that ran half a dozen queries, as a black box, applying it to every element in a list. For one element, this was a reasonable computation. It spat out the results in a little under a second. Naturally, when he took applied this to 20 list elements, the load time ballooned to 19 seconds. Multiply that by an average of 10 concurrent users, and you have pure CPU deadlock. (And a lot of angry customers!)

His method had significant computational overhead; table joins were performed repeatedly for each set of queries and, at each step, aggregated data (that would have been useful to other stages of computation) was discarded. So, I threw together a custom solution in a few hours and ran the same tests. My version ran in 0.7s (~93% faster).

I think it's an education problem. "Hold off the tough stuff until they've learned OOP; it's what business wants. With recent advancements in computing, the days of manually optimizing code are over. Relentlessly pursue code re-use and portability." That mentality doesn't always work. At some point, the control you lose when you layer: template over markup, over script, over server daemon, over virtual machine, alongside persistence layer, results in an army of programmers who can only tell you that they're finished coding, and it's too slow.

Thursday, July 17, 2008

ORA-02248: invalid option ...

ORA-02248: invalid option for ALTER SESSION
(Don't worry, this is the last of my scanned images)
.
This is one of the truly painful Oracle errors I've been forced to deal with in my time at UPS. It's probably comparable to the headaches accompanying FAST refresh on MVIEWS.
.
Since I haven't seen my version of the error treated satisfactorily yet, I thought I'd share my experience here. Every candidate solution I've found through Google, assumes that I've specified an invalid option in my ALTER SESSION command. None of them considered the possibility that a driver might be setting invalid options on my behalf. :P

My problem was the Oracle 10g JDBC driver I was using to access an Oracle 9i server. One would think that the drivers would be backwards compatible, but they're not. Worse still, I thought that I was out of luck, given that my application accesses data from 9i and 10g servers simultaneously.

However, all was not lost. Surprisingly enough, Oracle 9i client-side drivers are forward-compatible with 10g servers. So, the solution was to use an old JDBC driver.

Is Oracle mocking me?

ORA-02298: cannot validate
- parent keys not found
*Cause: an alter table validating constraint failed because the table has child records.
*Action: Obvious

I liked this, so I thought I would throw up a quick post. (Sorry about the image quality; It was a scan.)

Anyone who has used Access or Oracle long enough, really pushing the boundaries of what they can do, has likely come across an error or two that the developers never expected you would see. ("Invalid Argument", "out of memory", "Not enough space on temporary disk" [with 100gb free])

And then there are error messages that just seem like lapses in judgment... ;)

If anyone wants to know, a quick google search turned up a nice solution here:
http://www.dbforums.com/archive/index.php/t-988439.html
(The error message would have made a lot more sense if it said orphaned child records.)

Monday, July 14, 2008

The start of something small

A developer's blog is something I've always wanted to put together, but could never get around to. I guess real work takes precedence over documentation of the journey.

I'm hoping this blog will turn into a place where my ideas can set and mature, rather than a burial ground. That being said, I'm going to talk about: toy projects that fascinate me, particularly nefarious bugs (that I have yet to see discussed elsewhere) and, possibly, remark a little on the process of learning Japanese.

It should be fun. And, if you're reading this, thanks for visiting. :)