Showing posts with label vb6. Show all posts
Showing posts with label vb6. Show all posts

Friday, May 22, 2009

Speed Improvements... and Profiling.

It's incredibly important to profile before you begin to try and do any optimizations. The reasons for this should be obvious, but I've caught myself trying to do optimizations without profiling first. Bad idea. Sometimes you make things worse. It's also important to profile after every single change and not change multiple things at once. This lets you quickly determine if a change was good or bad.

MapX and RowValues

MapX is a 3rd party tool that displays geographical data. It is available from MapInfo (now owned by Pitney-Bowes) and is quite useful. It also hasn't been updated in about 7 years, since they have a new product called MapXtreme (what's so extreme about it?). Which means that we are stuck trying to pull performance out of a legacy application again that, well, isn't going to get any faster on it's own.

I made an interesting discovery a few weeks ago regarding accessing datasets. A dataset, in MapX terms, is a set of data associated with geographical data. While the map data (lat,long) is stored in a map file, the data is stored in a proprietary data format with a link between the data and the map object. There are times when we need to pull lots of data to display it to the user (an info tool, for example, so you can query what an object is on the map).

To access the data, you can directly refer to the dataset using the object's feature key. Something like:
strValue = dataset(feature key, field)
This works, but once need to query more than once against a row (or feature key), then it makes more sense to use a RowValues object, which is easy enough:
set rowValues = dataset.RowValues(feature key)
strValue = rowValues(field).Value
And there we go. For one value, the timing is similar. Once you do several requests in a row, however, it gets much faster. The more fields you read in a row, the higher the speed increase (economy of scale!).

Visual Basic 6 and Combo Boxes

Another fun thing discovered this week is that Visual Basic 6 is slow when adding lots of items to a combo box. How much is lots of items? Try 12,000 unique strings! So, off we go trying to find a better way. And, sure enough, there is a fairly simple way, as long as you don't mind getting your hands dirty with the windows messaging system api.

So we go from:
combobox.add "this string"
To:
SendMessage combobox.hWnd, CB_ADDSTRING, 0, ByVal "this string"
Simple enough, for a 50% time decrease for 12,000 items... from 1 second to 1/2 a second! Very good stuff.

MapX and Display

Some times measured speed doesn't mean that much to a user if it appears the system is hung and not doing anything at all.

Interestingly enough, MapX's map control has a setting called RedrawInterval. This setting sets how long between map redraws while the control is generating data to be displayed. A lower setting means that the map will be redrawn more frequently. A higher value means that the map won't update until it is done or the time has run out. When viewing a small section of a map, this doesn't make much difference.

What we discovered though, is that when a user is zoomed out to seeing a radius of 10km's worth of mapping data, the map is taking a while to redisplay for big cities. This makes sense, since there is a lot of road data to display for a large city... but, as it turns out, our RedrawInterval was set to 300, which translates to 3 seconds (who works in 1/100ths of a second?).

Setting it to the minimum of 10 (so 0.1 seconds) actually results in a perceived speed increase. Why? As it turns out, MapX draws each layer in sequence internally before displaying them. Since we have about a dozen layers (County, City, Railroads, Roads, Highways, etc...), this means that updates to the screen start happening sooner. Overall, the time taken to completely redraw the screen is longer (not by much, for larger cities it is about 2-3% slower on average, it's negligible for smaller cities/towns.), but, to the user, it appears to have drawn faster since they can see updates happening.

Friday, April 17, 2009

VB6, Collections and a mini-Rant

I enjoy where I work a lot. There are great people, an interesting and relaxed work environment and some interesting challenges.

But every once in a while, things turn a little sour... mostly when dealing with Visual Basic 6. To give any non-programmers a run down, VB6 is a crappy, slimmed down programming language that, thanks to it's ease of creating interfaces, became quite popular. But VB6 has a lot of limitations that just don't exist in other languages. Some of these are easier to get around than others... As an example, one of our applications has many issues with focus and how VB6 handles change of focus from other apps to itself. Or, rather, how it doesn't handle it nicely. Not pretty.

Today, I'm trying to add some functionality that should be quite easy. I want to use a dictionary to store some data. A dictionary stores data in it, using a key to reference a dataset (similar to a real life dictionary that uses a word to refer to a definition). Dictionaries are quite nice in that it is easy to look something up, since we just ask the dictionary for "ephemeral ", for example, and it returns it's definition "Short-lived; existing or continuing for a short time only" (Dictionary.com's word of the day). Dictionaries are simple, have a fast lookup (key for what I need) and store anything. VB6 has a container that is very similar to a dictionary, but is called a Collection.

The problem with collections is that they don't allow you to use user-defined structs. A struct is just a very simple way of combining some related data together. There is a different way of doing this called a class in VB6. Classes can be used with no problems with collections. So why am I complaining? Because I can place a struct inside the current codebase without having to add another file (each class in VB6 needs to have it's own file). I don't mind adding new files, but for something as minor as holding three items (that's right, just three), I now have to add an entire new file with a grand total of four lines of code in it. Four lines of code. Talk about a waste of time and space.

And don't get me started on classes in VB6. They are a perversion of the programming term class. But that's a rant for another day.