I sat on this idea for quite some time and would like to hear what you guys think about it.
The standard idiom for writing a singlet is something like this:
public class A {
...
private static A _instance;
public static A Instance() {
if(_instance == null) {
_instance = new A();
}
return _instance;
}
...
}
Here I propose another solution:
public class A {
...
private static A _instance;
public static A Instance() {
try {
return _instance.Self();
} catch(NullReferenceExceptio) {
_instance = new A();
}
return _instance.Self();
}
public A Self() {
return this;
}
...
}
The basic idea is that the time taken to complete 1 dereferencing and excluded exception is less than one zero check. I tried to measure a potential increase in performance, and here are my numbers:
Sleep 1sec (try / catch): 188788ms
Sleep 1sec (nullcheck): 207485ms
And the test code:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Diagnostics;
public class A
{
private static A _instance;
public static A Instance() {
try {
return _instance.Self();
} catch(NullReferenceException) {
_instance = new A();
}
return _instance.Self();
}
public A Self() {
return this;
}
public void DoSomething()
{
Thread.Sleep(1);
}
}
public class B
{
private static B _instance;
public static B Instance() {
if(_instance == null) {
_instance = new B();
}
return _instance;
}
public void DoSomething()
{
Thread.Sleep(1);
}
}
public class MyClass
{
public static void Main()
{
Stopwatch sw = new Stopwatch();
sw.Reset();
sw.Start();
for(int i = 0; i < 100000; ++i) {
A.Instance().DoSomething();
}
Console.WriteLine(sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for(int i = 0; i < 100000; ++i) {
B.Instance().DoSomething();
}
Console.WriteLine(sw.ElapsedMilliseconds);
RL();
}
#region Helper methods
private static void WL(object text, params object[] args)
{
Console.WriteLine(text.ToString(), args);
}
private static void RL()
{
Console.ReadLine();
}
private static void Break()
{
System.Diagnostics.Debugger.Break();
}
#endregion
}
10%, , , ( , , )?