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.

No comments:

Post a Comment