Monday, November 19, 2007

I decided to write this entry after seeing an article in codeproject describing the "disadvantage" of recursion. I won't put a link to the article because it's not an article worthy of reading, too much programming "don't dos".

Lets take for example the common use (i.e. the one every computer class use) calculating n!

the for loop looks like:

res = 1;
for(i=1;i<=n;i++) {
res *= i;
}


and the function looks like:

function calc(int n)
{
if (n>1) {
return calc(n-1)*n;
} else {
return 1;
}
}

The function will have to assign a new space for n in each iteration. That's a time consuming operation, but if I'll write the function:

function calc(ref int n)
{
if (n>1) {
return n*calc(--n);
} else {
return 1;
}
}

it would work faster, though no one would have the ability to decipher this call...

It looks like a loop is better than recursion because of the stack assignments, but that's incorrect. Basically it's a question of what's more appropriate for the problem at hand.
A loop is easier to handle for as long as it's a "short" calculation, by short I mean the number of lines. A recursive function is better for the cases where the operation is complicated, or if there are memory allocations you have to clear within the operation (in the .NET one can use GC.Collect(), but other languages don't have such a mechanism.)

Summarizing this article in one line:
You're a programmer, THINK BEFORE WRITING CODE!

Sunday, November 11, 2007

IP Mask Merging

I'm back after a week vacation. I was drafted to do nothing for a week, apparently I do to much work.
The issue for today is: IP mask, or how to merge a few subnets into a big subnet.
Easy said, not as easily done. The function I had to make has simple idea, "we have a range of IPs (startIP to endIP) and we want a subnet for it."

The resulting algorithm, I had to devise it after a failed algorithm didn't do the job, is as follows:
1. check the startingIP min bits (i.e. 192.168.0.0 is 192.168.0.0/13)
2. if the endIP matches the region made by this bits - hooray, we're done! if not move to 3.
3. if the endIP is bellow the available range - increase the bits, move to 2 else move to 4.
4. add the current subnet, and start the whole process with the range (startIP + (2 power (32-bits)) to endIP

Sorry I can't post the source code for copyright reasons, we're using it after all...

Important notes:
If you're using an IP to number conversion make sure it's a 4 byte unsigned (uint32) or in the case of vb/vbs use double (or force the result to be double by using cdbl(...))
Another point of interest is the "check the startingIP min bits" it's a bit wise comparison of the IP, a co-worker of mine used the following method:
find the relevant byte (byte1.byte2.byte3.byte4/bits) "AND" it with 256-(2 power (bits mod 8)), it's needed especially if you can't use a uint32.