tags:

views:

775

answers:

5

I was thinking about the classic issue of lazy singleton initialization - the whole matter of the inefficiency of:

if (instance == null)
{
    instance = new Foo();
}
return instance;

Anyone who knows what a Singleton is is familiar with the issue(you only need the if once). It's trivial but irritating.

So, I thought of an alternate solution, at least for .NET(although it should work anywhere that has some equivalent to function pointers:

public class Foo
{
    private delegate Foo FooReturner();

    private static Foo innerFoo;

    private static FooReturner fooReturnHandler = new FooReturner(InitialFooReturner);

    public static Foo Instance
    {
        get
        {
            return fooReturnHandler();
        }
    }
    private static Foo InitialFooReturner()
    {
        innerFoo = new Foo();
        fooReturnHandler = new FooReturner(NewFooReturner); 
        return innerFoo;
    }

    private static Foo NewFooReturner()
    {
        return innerFoo;
    }

}

In short - the Instance returns a delegate method. The delegate is initially set to a method that initializes your instance, then changes the delegate to point at a simple Return method.

Now, I like to think I'm not terrible at my job, but I have no pretensions about being awesome. I have not seen an example of this code anywhere.

Ergo, I come to the conclusion that I am missing something. Something major. Either that the whole problem is too trivial to bother thinking that much about or this does something horrible that will destroy the universe. Or I fail at searching and therefore haven't seen the hundreds of developers using this method. Something, anyway.

I was hoping the good folks here at Stack Overflow could clue me in as to what(leaving aside the controversy on whether one should use a Singleton at all).

EDIT for clarification:

This is not performance code(although if the design actively degrades performance beyond the traditional model, that would be interesting to know).

It was written purely as proof-of-concept, and I am further aware that it is not thread-safe as it properly should be. Is there any reason why it could NOT be made thread-safe by it's very nature?

+21  A: 

This is the canonical, thread safe, lazy Singleton pattern in C#:

public sealed class Singleton
{
    Singleton(){}
    public static Singleton Instance
    {
        get
        {
            return Nested.instance;
        }
    }        
    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested() {}    
        internal static readonly Singleton instance = new Singleton();
    }
}
Randolpho
And for Java programmers, the equivalent is called the "Lazy Initialization Holder Class" idiom, described in Item 71 of Effective Java 2nd ed. :-)
Chris Jester-Young
That my be lazy to the MySingleton type, but it isn't necessarily granular to the .Instance property
Marc Gravell
See Jon's article referenced in Marc's answer; the "canonical" pattern may not be as lazy as we would like it to be.
AnthonyWJones
We had linked the same article, but my short simplification was ill-advised. Ultimately, I have edited to duplicate Marc's answer. He should be given the accepted answer.
Randolpho
Nah - I'll delete mine; you can have it ;-p
Marc Gravell
@Marc Gravell: you didn't have to do that. Unless you were wanting a certain badge... :)
Randolpho
You mean Disciplined? Already got it; it doesn't stack...
Marc Gravell
Really? It should.
Randolpho
Sorry for the previous french... this code marks Singleton with beforefieldinit AND Nested with beforefieldinit. Is marking Singleton with beforefieldinit really needed?
Sam Saffron
+1  A: 

the whole matter of the inefficiency of:...

What inefficiency?

Those instructions will result into an extremely fast fragments of assembly code. I am completely sure that there is nothing to be gained by trying to "optimize" this. Even if you come up with something faster, it will be at a significant complexity cost.

Unless you do have positive evidence that this code is affecting your performance, you should use the simplest approach that solves your problem.

Euro Micelli
while simple, the null-check approach isn't actually thread-safe...
Marc Gravell
That said, the approach you are displaying, is conceptually a well-known pattern in use for many years for JIT (Just-In-Time) compilation, including .NET's "IL" itself: When a function call is found, it is made to "point" to a compiler call for the source of the function. The first time it's called, what runs is the compiler, which compiles the fragment into machine code and replaces the reference to point to the newly compiled code. Finally, the new code is called and the compiled gets out of the way. JIT is a furiously performance-critical scenario that justifies this kind of complexity.
Euro Micelli
@Mark Gravell: > while simple, the null-check approach isn't actually thread-safe... < -- Correct. If the singleton will be called from multiple threads, you should use the Double-checked locking pattern, which is actually guaranteed to work in .NET
Euro Micelli
I wasn't actually aiming for a performance gain - this was purely done on a whim, since I feel it adds a bit of elegance. What puzzles me, as I said, is why I haven't seen it before. Surely I can't be the first to have thought of it?
Faqa
+4  A: 

Have you measured the performance?

Do you believe that an additional function call is cheaper than an if?

I agree with the others that using the static ctor works well for this initialization. This will also get rid of the inherent race condition that the you have since .net guarentees that static constructors will only be called once.

Jack Bolding
I agree, a null check is definitely faster than a method call...
Thomas Levesque
+7  A: 

To prevent from having to copy the singleton code, you could make the type generic, as such:

public abstract class Singleton<T>
    where T: class, new()
{
    public static T Instance
    {
        get { return Nested.instance; }
    }

    private class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested() { }

        internal static readonly T instance = new T();
    }
}

public sealed class MyType : Singleton<MyType>
{
}

class Program
{
    static void Main()
    {
        // two usage pattterns are possible:
        Console.WriteLine(
            ReferenceEquals(
                Singleton<MyType>.Instance, 
                MyType.Instance
            )
        );
        Console.ReadLine();
    }
}
oɔɯǝɹ
A: 

I always use this regular (non-lazy) one (you could nest it like the other examples): (requires using System.Reflection;)

public class SingletonBase<T> where T : class
{
    static SingletonBase()
    {
    }

    public static readonly T Instance = 
        typeof(T).InvokeMember(typeof(T).Name, 
                                BindingFlags.CreateInstance | 
                                BindingFlags.Instance |
                                BindingFlags.Public |
                                BindingFlags.NonPublic, 
                                null, null, null) as T;
}
Cade Roux
I would add the new() constraint to type parameter T. Otherwise this will result in runtime errors.
oɔɯǝɹ
I don't allow my singletons to have a public constructor.
Cade Roux
Can you post this on http://stackoverflow.com/questions/100081/whats-a-good-threadsafe-singleton-generic-template-pattern-in-c its the closest to a correct answer I have seen.
Sam Saffron