Alright I got a question for you all that I just can't seem to figure out if it's working as I expect it to or not.

Recently I have begun re-writing a piece of code I wrote that is used to generate QR Codes (square barcodes). Part of the reason I am doing this is try and improve its performance and memory footprtint, and clean up the code from a maintance point. Now granted it probably isn't a big issue on these, but I am doing it to try and teach myself better coding standards.

Anyway, one of the part is initializing variables only when I need them, even if static. These are constant variables, that won't change, but at the same time, there are multiple of them, so at any time, only one collection might be needed. Here is a snippet of some code I have written.

private static Dictionary<ErrorCorrectionLevel, int []> _NumericLengths;

#region NumericLengths
/// <summary>
/// Get the collection of Numeric Encoding Version Lengths
/// </summary>
private static Dictionary<ErrorCorrectionLevel, int []> NumericLengths
{
    get
    {
        if (_NumericLengths == null)
        {
            _NumericLengths = new Dictionary<ErrorCorrectionLevel, int []>();
            _NumericLengths.Add(ErrorCorrectionLevel.L, new int [] { 41, 77, 127, 187, 255, 322, 370, 461, 552, 652, 772, 883, 1022, 1101, 1250, 1408, 1548, 1725, 1903, 2061, 2232, 2409, 2620, 2812, 3057, 3283, 3514, 3669, 3909, 4158, 4417, 4686, 4965, 5253, 5529, 5836, 6153, 6479, 6743, 7089 });
            _NumericLengths.Add(ErrorCorrectionLevel.M, new int [] { 34, 63, 101, 149, 202, 255, 293, 365, 432, 513, 604, 691, 796, 871, 991, 1082, 1212, 1346, 1500, 1600, 1708, 1872, 2059, 2188, 2395, 2544, 2701, 2857, 3035, 3289, 3486, 3639, 3909, 4134, 4343, 4588, 4775, 5039, 5313, 5596 });
            _NumericLengths.Add(ErrorCorrectionLevel.Q, new int [] { 27, 48, 77, 111, 144, 178, 207, 259, 312, 364, 427, 489, 580, 621, 703, 775, 876, 948, 1063, 1159, 1224, 1358, 1468, 1588, 1718, 1804, 1933, 2085, 2181, 2358, 2473, 2670, 2805, 2949, 3081, 3244, 3417, 3599, 3791, 3993 });
            _NumericLengths.Add(ErrorCorrectionLevel.H, new int [] { 17, 34, 58, 82, 106, 139, 154, 202, 235, 288, 331, 374, 427, 468, 530, 602, 674, 746, 813, 919, 969, 1056, 1108, 1228, 1286, 1425, 1501, 1581, 1677, 1782, 1897, 2022, 2157, 2301, 2361, 2524, 2625, 2735, 2927, 3057 });

        }

        return _NumericLengths;
    }
}

#endregion

The idea behind this is the code won't initialize the Dictionary of "NumericLengths" until I need it. That way I lower the memory footprint, as well as not having to initializing multiple collections (there are 4 of these properties). However, once I have initialized it, since it's static, it's in memory for me to use until the application is finished.

However, as I remember, static variables are initialized at run time. Also, when it comes to Get/Set, I have seen some mixed results. There have been times I feel they initialize themselves, even before anyone accesses them, while other times they only do upon access.

So my question for you all is this. Is this really working in the sense that the Get will not initialize the collection until the first time it is accessed? Or because it's static, it's initializing it right away, despite it being a Get.

Thanks

Edited 8 Months Ago by JOSheaIV

The compiler has to include all those values in your runtime, so any saving is pretty illusionary. Exactly how many bytes/CPU cyles are you saving? As a percentage of the hardware capacity? How many nanoSeconds per run?
Don't waste any more time on this kind of "premature optimisation" and concentrate on writing code that you sucessor can fix/update easily.

Unless you are in some special limited hardware environment, "better coding standards" means "easier to maintain", not "saves a nanoSecond on startup".

So while that seems to make sense, here's something interesting.

I rigged up the following piece of code (see below). What was interesting is within a different class, where I tried to access this class (if I recall right I had a generic constructor). Anyway, I could consistently access the class variable (not the property), and never had an issue. The value remained null. It wasn't till I called the property that the exception was thrown.

public static string _TestValue = null;

public static string TestValue
{
    get
    {
        if(_TestValue == null)
        {
            throw new Exception("");
        }

        return _TestValue;
    }
}

So I am wonder, while what you said does make sense, how does this work? I mean usually when you think static, you think initialized at runtime. Yet this property never even tried to do anything with itself until I tried to access it. Are properties more then just a variable?

Edited 8 Months Ago by JOSheaIV

https://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx

You can use a static constructor to initialize your fields. The only problem is that you have absolutely no control over when this happens. The only thing you can be sure of is that it will be called before any call.

A property is a wrapper around your field. It controls access to the class internal data. In your case both are public, which is rather confusing. A user of your class could choose which of the two to use, that is not what you want.

One sidenote. Be careful when using statics in web server code. The effects may be undesired.

Edited 8 Months Ago by pritaeas

Thank you pritaeas. The code I posted there was just used as test code (to show the static property itself doesn't initialize right away). I am just trying understand the underlaying logic of properties better. I use these a lot, but realized when it comes to my static ones (which I don't use often).

Again I have a project that I initialize for instance these static properties when they are first called. They are populated with a collection of data. The reason behind this was the data is constant so once initialized it won't change, and could be used across all classes for the life of the application. However, I don't initialze it all at once to prevent loading time and a larger memory footprint that's needed.

The application I am currently doing this on is more to improve my skills, so I was inquiring more on the details of how static properties work in respect to the items above. Do I really gain the benefit, and how exactly are they working (because in my later example, I see that property doesn't initialize itself right away, why I was using public so I could access both variables externally to test it)

Edited 8 Months Ago by JOSheaIV

This article has been dead for over six months. Start a new discussion instead.