Shopping for old tech

Posted on February 22, 2009 by Steve

My lady friend is out of town on Oscar night, and I promised to record the show for her. Come the day of the event, and I realize I am caught between eras. No DVR, not even a TV-ready video card. And I had to pause to remember where our VCR was. I found it in a guest room, in use as a remote-friendly tuner for my first TV, a 13-inch RCA tube with knobs.

I felt sure we had some tapes stacked up somewhere, and planned to record over a Seinfeld collection. But they must have gone out with the trash, sometime before the Great Divestment of 2008. I went to three stores looking for videotape, and took advantage of the chance to pick up some edamame. Rite Aid hooked me up with some Maxell tape and an impulse-buy 1GB SD card for $3 after rebate.

Now I just have to get through 24 hours without finding out who got Best Picture.

Speedy generics

Posted on February 20, 2009 by Steve

In the Microsoft Press Training Kit for MCTS Exam 70-536, Tony Northrup writes:
I haven't been able to reproduce the performance benefits of generics; however, according to Microsoft, generics are faster than using casting. In practice, casting proved to be several times faster than using a generic. However, you probably won’t notice performance differences in your applications. (My tests over 100,000 iterations took only a few seconds.) So you should still use generics because they are type-safe.
I recently found that using generics offered a significant improvement to a complicated patch of code I'm working on. Here's a simple demonstration.
Dim ht As New Hashtable
Dim sw As New System.Diagnostics.Stopwatch
sw.Start()
For i As Integer = 1 To 10000
    For j As Integer = 1 To 10000
        If ht.Contains(i) Then
            ht(i) = j
        Else
            ht.Add(i, j)
        End If
    Next
Next
sw.Stop()
Console.Write("Hashtable time(ms): " & sw.ElapsedMilliseconds)
Average time over six runs was 11157 ms for a debug build and 11305 for a release build, compared to:
Dim sw As New System.Diagnostics.Stopwatch
Dim dic As New Dictionary(Of Integer, Integer)
sw.Start()
For i As Integer = 1 To 10000
    For j As Integer = 1 To 10000
        If dic.ContainsKey(i) Then
            dic(i) = j
        Else
            dic.Add(i, j)
        End If
    Next
Next
sw.Stop()
Console.Write("Generic dictionary time(ms): " & sw.ElapsedMilliseconds)
which took 4431 ms in debug and 3610 in release, improvements of 60% and 68% respectively.

I was clued in to the cost of boxing and unboxing by dotTrace, a handy profiler with a ten day trial. It burrowed into my thousand-line mass of code and showed that 85% of the method's runtime was consumed by CompilerServices.NewLateBinding.LateIndexGet and LateGet calls. The next most expensive method was SortedList.get_Item, using only 1% of the overall time, despite being called a third as often as the other two methods combined.

So I dumped my HashTables and ArrayList objects in favor of generic Dictionary(of String, String) and List(of String) objects. With these generics, the late binding was eliminated and the sprightly get_Item now represented 8% of the runtime, while overall performance was nicely improved.

But why are these collections, which require you to specify the datatypes that they contain, called "generics"? It makes sense, in a way. You do have to specify their contents, but generic collections can contain any type, whereas non-generic collections can contain only Objects.

The Hours

Posted on February 13, 2009 by Steve

Here's one for the Art of Noise fan(s) in the audience.

The Hours
Can You See The Light
No singing, synthesized melody, driving rhythm, and an insistent cow bell. What more could you ask for?