Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WPF: Getting Rid of magic strings Reduces Speed

0.00/5 (No votes)
2 May 2016 1  
Speed reduction that may occur when using expressions instead of string constants in INotifyChanged paradigm and a way to work around this

Introduction

A common practice is to use lambda expressions instead of string constants - "magic strings" - as the names of the properties in the INotifyChanged paradigm: something like NotifyPropertyChanged(()=>Property); instead of NotifyPropertyChanged("Property");
We will show that this reduces the speed of Binding execution. Also, we will show a trivial way to work around this.

Property Name Infer From Expression

Generally such construction requires a property name infer from the expression:

public static string NameInfer<T>( Expression<Func<T>> itemExpression )
{
    switch ( itemExpression.Body.NodeType )
    {
        case ExpressionType.Constant:
        default:
            return ( ( itemExpression.Body as ConstantExpression ).Value as String );

        case ExpressionType.MemberAccess:
            return ( ( itemExpression.Body as MemberExpression ).Member.Name );
    }
}

This calculation takes a certain time. Below - the results of time testing. An average of twenty thousand fold sendings of a text ("Lorem ipsum...") to property is calculated. Left side column - result for string constant property name; middle column - result for expression derived property name:

Numerical values above may seem ridiculous, but with intensive communication between View and ViewModel can be significant; timing difference also becomes important in the case of ViewModel - ViewModel communications.

Repair

Fortunately repair is straightforward and somewhat dull. It is enough to declare readonly string variables and evaluate them once in a ViewModel's constructor using expression to string conversion, and to use these variables instead of constant property names in all further calls to NotifyPropertyChanged - something like in the code snippet below:

    ...
private readonly string sr_view1Text2;
    ...
#region ctor
public View1Model()
{
    ...
    sr_view1Text2 = NameTypeHelper.NameInfer( ( ) => View1Text2 );
    ...
}
#endregion ctor

    ...
private string _view1Text2;
public string View1Text2
{
    get { return _view1Text2; }
    set
    {
        if ( _view1Text2 != value )
        {
            _view1Text2 = value;
            NotifyPropertyChanged( sr_view1Text2 );
        }
    }
}

Below - the results of testing: left side column - timing for constant string property name, middle column - for expression derived property name and the right side column - for readonly string variable which value is derived from expression only once.

Timings for "magic strings" property names and readonly string variable property names are the same.

History

  • 3rd May, 2016: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here