Efficiency: Func<T>, Vs instance of T

.net, c#, functional-programming, generics

Solution

This is the code I used for the benchmark:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace ConsoleApplication3
{
    using System.Collections;
    using System.Diagnostics;
    using System.Globalization;
    using System.Numerics;
    using System.Xml.Linq;

    public class Program
    {

        public class Person
        {
            private string _name = string.Empty;

            private int _age = 0;

            private bool _isMale = true;

            public Person(string name, int age, bool isMale)
            {
                this.Name = name;
                this.Age = age;
                this.IsMale = isMale;
            }

            public string Name
            {
                get
                {
                    return this._name;
                }
                set
                {
                    this._name = value;
                }
            }

            public int Age
            {
                get
                {
                    return this._age;
                }
                set
                {
                    this._age = value;
                }
            }

            public bool IsMale
            {
                get
                {
                    return this._isMale;
                }
                set
                {
                    this._isMale = value;
                }
            }
        }

        private static void Main(string[] args)
        {
            var myDictionary = new Dictionary<string, Person>();
            myDictionary.Add("notRichard", new Program.Person("Richard1", 26, true));
            myDictionary.Add("notRichard1", new Program.Person("Richard2", 27, true));
            myDictionary.Add("notRichard2", new Program.Person("Richard3", 28, true));
            myDictionary.Add("notRichard3", new Program.Person("Richard4", 29, true));
            // usage
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for(int i = 0; i < 100000000; i++)
            {
                var myValue = myDictionary.GetValueOrDefault("Richard", new Program.Person("Richard", 25, true));
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 100000000; i++)
            {
                var myValue = myDictionary.GetValueOrDefault("Richard", ()=> new Program.Person("Richard", 25, true));
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadKey();
        }
    }
    public static class Ex
    {
        public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> source, TKey key, TValue @default)
        {
            if (source.ContainsKey(key))
            {
                return source[key];
            }
            return @default;
        }
        public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> source, TKey key, Func<TValue> defaultSelector)
        {
            if (source.ContainsKey(key))
            {
                return source[key];
            }
            return defaultSelector();
        }


    }
}

Calling each extenssion method 100000000 times (without finding an entry, hence causing Func to be executed each time) gives the following result:

`T` - 10352 ms

`Func<T>` - 12268 ms

Calling each extenssion method 100000000 times (and finding an entry, hence not calling Func at all) gives the following result:

`T` - 15578 ms

`Func<T>` - 11072 ms

Hence, which one performs quicker depends of how many instantiations you save and how expensive is each instantiation.

Optimising the code a bit by reusing the default person instance gives 6809 ms for `T` and 7452 for `Func<T>`:

            Stopwatch sw = new Stopwatch();
            var defaultPerson = new Program.Person("Richard", 25, true);
            sw.Start();
            for(int i = 0; i < 100000000; i++)
            {
                var myValue = myDictionary.GetValueOrDefault("Richard", defaultPerson);
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 100000000; i++)
            {
                var myValue = myDictionary.GetValueOrDefault("Richard", () => defaultPerson);
            }

So, in theory (if you take instantiation out of the equation), saving a hop in the call stack gives you some performance gain, but in practice, this gain is negligible.

Problem

Recently I've been experimenting with the use of the `Func<T>` class, and so far I'm loving it. I've noticed however that more and more I'm beginning to use it instead of actually using an instance of `T`, so I wanted to ask; what's the overhead of using `Func<T>` vs `T`? I know this is a somewhat generic question, as `T` can be anything, so I guess that question should maybe be focused towards, what is the overhead of passing a function, rather than an instance of a simple object? For the sake of argument, let's assume the following. Our mock object, `T` ``` public class Person { private string _name = string.Empty; private int _age = 0; private bool _isMale = true; public Person(string name, int age, bool isMale) { this.Name = name; this.Age = age; this.IsMale = isMale; } public string Name { get { return this._name; } set { this._name = value; } } public int Age { get { return this._age; } set { this._age = value; } } public bool IsMale { get { return this._isMale; } set { this._isMale = value; } } } ``` Now, let's say we have a pretty extension method on `IDictionary`, that selects the value by the key, or a default value. The pseudocode could be described as follows: Is the key found in the KeyValuePair collection Yes, return the value No, return the default Option 1. Our extension method using an instance of `T` ``` public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary source, TKey key, TValue @default) { if (source.ContainsKey(key)) { return source[key]; } return @default; } // usage var myValue = myDictionary.GetValueOrDefault("Richard", new Person()); ``` Option 2. Our extension method using `Func<T>`... mmm, pretty! ``` public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary source, TKey key, Func<TValue> defaultSelector) { if (source.ContainsKey(key)) { return source[key]; } return defaultSelector(); } // usage var myValue = myDictionary.GetValueOrDefault("Richard", () => new Person("Richard", 25, true)); ``` Comparison Comparing the above options, it's clear that there are potential benefits of both. Option 1 is slightly easier to read, however I'm currently loving the usage of `Func<T>`, and therefore to me option 2 seems ideal. I guess I'm considering it a lazily-instantiated parameter, that is only executed when it's needed, therefore saving on efficiency, but am I right?

Original source