Monday, June 22, 2009

VB6 Speed Tests I

This will be a multipart series to explain how to do some speed testing/throughput of a program.
So I was thinking about this the other day,I have a few programs that take a little bit to get setup and start running. I found that I would really like to know how long it takes for a particular function to run. In the past I usually just stick a timer of some sort at the beginning and end of a particular function.

This works great for a particular function, but lets say you have a fairly large program and would like a big picture of the times of the entire program?

I got to thinking about it, now the particular version of the code that I wanted to time was actually VB6 code, so I thought "hey I can write a perl program that will just open these files up and add 3 variables in the beginning get the clock count, then move to the end of the function and get the clock count and then print it out to an output file.

So I got going....Follow along if you dare....

So let's work out an algorithm or a set of steps that we are going to attempt to do!
  1. Search for anything in the file that starts with Public/Private Sub/Function
  2. Insert our initialization of our variables and code for getting initial clock time
  3. Search for End/Exit Sub/Function
  4. Insert code to get the last clock value.
  5. Insert code to calculate the diff from the end time-start time
  6. Insert code to print out the value last calculated.
* A catchya I found was that even though I was opening .cls files, there is text at the beginning of the file to I suppose initialize the class as VB is opening, what this amounts to is that you have now stuck a "declaration" before the page was setup, so you'll need to trigger on sticking the code in right after this chunk of "header" data.

So now what we will hopefully have (by this point), will be the times that each function is running, also how many time's it's ran (because EVERY TIME it is ran it will print out a time).

Let's start taking apart this file I wrote up...I'm sure it can be modified to work with most programming languages...but this one will specifically explain for VB6 (possibly working for VB.Net+)

@file_list = <*.cls>; #match the normal cls file extensions

So here we want to get a list of all the .cls files in the folder (since most of my functions are here this is where we'll start anyways!

foreach $file (@file_list) {
open DATAFILE, "$file" or die "Missing $filename file.\n";
open (DATAFILE, $file);
@filenames = ;

close (DATAFILE);

$one = 0;
for( my $n=0; $n < scalar(@filenames); $n++)
{
if ($filenames[$n] =~ m/^\s*(Public|Private) (Function|Sub)/)
{
$one++;
}
}

if ($one > 0)
{
open (OUT, ">$file");
}
else
{


}


So what we've done is we read in each file check to see if there are functions and if there are we open the stream to output our updated file contents to.

The interesting thing to note is that we used a nice regular expression I managed to learn from the regular expression book published by O Reilly, I plan to do a book review on it in the near future,

m/^\s*(Public|Private) (Function|Sub)/

Now the interesting thing to see is that there is always more then one way to do things, and I feel like this looks way better then:
m/^(\s+|)Public Function|^(\s+|)Public Sub|^(\s+|)Private Sub|^(\s+|)Private Function/

So what I am doing is searching for a string starting with none or more spaces containing either public or private, AND either function or sub, the top example shows it much more elegantly.

Stay tuned as I write more follow on posts.