Monday 26 October 2015

C# fun

All of us know that look ups are faster than search. OK, but how much? Let us measure.

Stopwatch sw = new Stopwatch();

int count = 100000;

int[] arrayA = new int[count];

int[] arrayB = new int[count];

Dictionary dictA = new Dictionary();

Dictionary dictB = new Dictionary();

Hashtable hashA = new Hashtable();

Hashtable hashB = new Hashtable();

bool[] leftOnlyMatch = new bool[count];

for(int i = 0; i < count; i ++)

{

arrayA[i] = i;

dictA.Add(i, null);

hashA.Add(i, null);

arrayB[i] = i + 5000;

dictB.Add(i + 5000, null);

hashB.Add(i + 5000, null);

}

sw.Start();

for (int i = 0; i < count; i++)

{

var item = arrayA[i];

if(!arrayB.Any(x => x == item))

{

leftOnlyMatch[i] = true;

}

}

sw.Stop();

Console.WriteLine("Time elapsed:" + sw.ElapsedMilliseconds);

sw.Reset();

sw.Start();

for (int i = 0; i < count; i++)

{

var item = arrayA[i];

if (!dictB.ContainsKey(item))

{

leftOnlyMatch[i] = true;

}

}

sw.Stop();

Console.WriteLine("Time elapsed:" + sw.ElapsedMilliseconds);

sw.Reset();

sw.Start();

for (int i = 0; i < count; i++)

{

var item = arrayA[i];

if (!hashB.ContainsKey(item))

{

leftOnlyMatch[i] = true;

}

}

sw.Stop();

Console.WriteLine("Time elapsed:" + sw.ElapsedMilliseconds);

The output is (release mode, 32 GB RAM, 4 dual core processors)

Time elapsed:36244
Time elapsed:1
Time elapsed:2
Press any key to continue . . .


There you go. Dictionary seems slightly faster than Hashtable and it seems only logical.

Fun point

What's wrong with this code?

var testResult = test.Where(x => x == "1111").Select(y => y.Length).First();

There are 2 issues:

1. It assumes that Where clause will always return results.
2. It uses 3 operations for something that is possible with just 1.

var testResult = test.FirstOrDefault(x => x == "1111");
var length = testResult != null ? testResult.Length : 0;








Sunday 11 October 2015

Configuration and Settings: where do you keep these?

This has been a contentious point and I am sure everyone finds a suitable explanation to justify why they have a certain setting in the store of their choice. Generally in .NET world, we have 2-3 options to store application specific configurations/settings.

1. App.Config/Web.Config: These are the most used files to store any setting value whether it be through appSettings section or a custom section. It is super easy to encrypt the file and there is no overhead attached to dealing with encrypted configuration file. In case of ASP.NET deployments, it is slightly more cumbersome as the files needs to be copied across all servers and you need to ensure that all servers have the same file content.

2. External config/files: Less used. It is fairly useful in cases where a common setting value needs to be applied to multiple applications. It is also helpful in multi server deployments if you don't want to have one file replicated across servers. One of the downsides of this approach is that it can not be seamlessly used if it is encrypted. You need to apply hacks.

Both 1 & 2 do not allow strong typing in settings by default. You end up writing a custom configuration section to ensure it is strongly typed. If you don't, then your appSettings will be of keys that have comma (or semicolon or pipe) separated strings :)


3. Remote Store (Database/WebService): This is where things start to get interesting. The moment you decide to start moving configuration settings to a remote store like database, you start asking - is app.config required for storing database connection string only? In my opinion, that is a good enough use. In fact, I am of the opinion that some senior person (may be a guy who knows business side of things) reviews all of your appSettings to identify what are actual Business Configurations and what are simple Technical Configurations. Once you are through with that exercise, you would find it easy to decide what configuration needs to be moved to a remote store and what needs to reside in app.config. One crude way (but not the most effective way) to identify that is to identify the settings that would require you to restart process (appPool or service). Those settings should remain in app.config/web.config. One of the downside that you may find is that you need to find a custom encryption implementation to safeguard the settings that have been moved to a remote store (provided that those settings are actually required to be encrypted).


I personally prefer the usage of remote storage where I can store my complex configurations (and make those versioned) in JSON format. The only challenge that I have noticed in this case is that application needs to have some custom implementation to detect and refresh the configuration changes. I bet that it is not too hard to write one.


I have been part of some big teams and one of the things that I have learnt is that you need to learn to control the usage of app.config for storing configurations as developers may end up filling this file with just too many settings. In fact, I would argue that you need to question the modularity of design if the application's appSettings shows more than 5 settings (yeah, it is harsh). And the debate rages on...