Search code examples
vb.netclr

Converting large global statically allocated arrays to Collections


I am working on retrofitting an application written in VB.NET. It is a simple program that uses 0.5GB (!) of RAM, because of a large amount (30+) of globally defined arrays, like:

Public Temp(1000000) As Double
Public ThisIsAnotherVariable(5000, 10) As String 
Public ThisIsAVeryLargeArray(64, 50000) As Double

Most of the time, these large "buffers" are barely used, so I would like to convert them to use something from Collections.Generic. Is there any semi-transparent way to convert these? Or a bit of trickery to get the CLR to only allocate the used segments?


Solution

  • If these are "sparse" arrays, i.e., if almost all array entries are entries, the simplest solution might be to replace them with dictionaries:

    Public Temp(1000000) As Double                     ' Old
    Public Temp As New Dictionary(Of Int32, Double)()  ' New
    

    Assignment would be source-code compatible:

    Temp(10) = 2.0    ' Works for arrays and dictionaries
    

    Reading would be source-code compatible, if the value is present:

    Dim x = Temp(3)   ' Works for arrays and dictionary, if Temp(3) has been assigned
    

    However, accessing values which have not been assigned will yield a KeyNotFoundException. If you need that, you'd have to use a "default value dictionary" instead of a regular dictionary. Unfortunately, no such dictionary is built-in in the BCL, but there are others who have already looked at that problem and shared their implementation. If you want to use a plain .NET dictionary, you will need to replace every read access with a method call.