Performance in .NET – Part 2

Introduction

This is the second in a series of posts about performance in the .NET ecosystem. On the first post, that you can find here, I talked about object instantiation. This time, it’s object cloning.

Object Cloning

You should be aware that there are two types of cloning:

  • Deep cloning: clones the root object and each reference its properties points to
  • Shallow cloning: clones the root object but each reference any of its properties points to is kept, that is, is also pointed to, not cloned

Microsoft defines one interface, ICloneable, which is implemented by a couple of classes, but doesn’t really say much about the type of cloning that it does. In fact, Microsoft actually advises against using it.

Sometimes we definitely need to make a copy of an existing object. This includes creating a new instance and then populating it with the values (or copies of) for the properties of the initial class. We have a few options:

  • Using the built-in MemberwiseClone method
  • Implementing our own cloning strategy
  • Using an object-to-object mapper
  • Serializing and deserializing

Memberwise Shallow Clone

The Object class defines a MemberwiseClone method that the documentation describes as doing a shallow copy of the current object. Because this is defined for Object, all classes inherit it, and it will make a copy of all fields declared along the class hierarchy. But, alas, being generic also means that it is not particularly suited for any concrete scenario. It uses it uses FormatterServices.GetUninitializedObject to create a “blank” instance of your class and then reflection to iterate through all of the instance fields of your class and makes a bitwise copy of them. Because of the reflection part, it’s probably not the fastest solution.

Custom Clone

Here you need to decide if you’re going for a shallow or a deep strategy, and depending on that, things can be more or less complicated. In general, a shallow copy is faster and simpler to implement as we know exactly what properties to copy, and you can even go for a shallow or a deep copy. An option is to use an object mapper.

Using a Mapper

Using a mapper such as Automapper can prove very useful as it can do lots of things out-of-the-box for you and still leave you space to handle any more complex situations. There are many out there, but Automapper is probably the most popular but there are alternatives:

So, the idea is, you construct the target instance (the copy) yourself and then you use the mapper to copy from the current instance into it. A decent mapper can use conventions to copy without requiring any configuration, but it will still require some reflection magic.

Serializing and Deserializing

This one, like using a mapper, also requires a third-party library. There are plenty out there, even included in the .NET framework, that can do this. This may seem like an overkill if you’re just trying to get a clone of your current object, but it works, and it is usually one of the easiest ways to get a deep copy. This is usually used for transmitting an object’s state over the wire, in any format that can be binary or text-based, and it can go back as well, translating this state back into a class. Usually also not the fastest approach, especially for complex object graphs.

Conclusion

Performance-wise, you’re probably better off by rolling out your cloning method, which will probably be unique for each class. This avoids reflection and serialization (which also uses reflection). Just make it clear to everyone that you’re implementing a shallow or a deep copy.

Performance in .NET – Part 1

Updated: thanks, Paulo Morgado!

Introduction

Along the years I wrote a couple of posts about performance in the .NET world. Some were more tied to specific frameworks, such as NHibernate or Entity Framework, while others focus on the generic bits. In this series of posts I will summarize my findings on .NET in general, namely:

  • Object creation (this post)
  • Object cloning
  • Value Types versus Reference Types
  • Collections
  • Possibly other stuff

I won’t be talking about object serialization, as there are lots of serializers out there, each with its pros and cons. In general, I’d say either serializing to and from JSON or from a binary format seem to be the most demanded ones, and each has quite a few options, either provided by Microsoft or from third parties. The actual usage also affects what we want – is it a general-purpose serializer or one for a particular usage, that needs classes prepared accordingly? Let’s keep it out of this discussion.

As always, feel free to reach out to me if you want to discuss any of these! So, lets start with object creation.

Object Creation

Let’s start with object creation and by defining our purpose: we want to be able to create object instances of a certain type as fast as possible. We have a couple of strategies:

Let’s cover them all one by one.

Using the new Operator

This is the most obvious (and fast), but does not play well with dynamic instantiation, meaning, the type to instantiate needs to be hardcoded. I call it direct instantiation, and it goes as this (you know, you know…):

var obj = new Xpto();

This should be the baseline for all performance operations, as it should offer the best possible performance.

Using Reflection

Here I’m caching the public parameterless constructor and invoking it, then casting the result to the target type:

var ci = typeof(Xpto).GetConstructor(Type.EmptyTypes);<br />var obj = ci.Invoke(null) as Xpto;

Just avoid getting the constructor over and over again, do it once for each type then cache it somewhere.

Using FormatterServices.GetUninitializedObject

The GetUninitializedObject method is used internally by some serializers and what it does is, it merely allocates memory for the target type and zeroes all of its fields, without actually running any constructor. This has the effect that any explicitly declared field and property values will be lost, so use with care. It is available in .NET Core:

var obj = FormatterServices.GetUninitializedObject(typeof(Xpto)) as Xpto;

Pay attention that none of the constructors of your type are executed, and no fields or properties have their initial values set, other than the default value for each type (null for reference types, the default for value types).

Using System.Reflection.Emit code generation

This one uses the code generation library that is built-in with .NET (but not .NET Core, for the time being):

var m = new DynamicMethod(string.Empty, typeof(object), null, typeof(Xpto), true);<br />var ci = typeof(Xpto).GetConstructor(Type.EmptyTypes);<br />var il = m.GetILGenerator();<br />il.Emit(OpCodes.Newobj, ci);<br />il.Emit(OpCodes.Ret);<br />var creator = m.CreateDelegate(typeof(Func<object>)) as Func<object>;<br />var obj = creator() as Xpto;

As you can see, we are just generating code for a dynamic method, providing a simple content that does “new Xpto()”, and execute it.

Using Activator.CreateInstance

This is essentially a wrapper around the reflection code I’ve shown earlier, with the drawback that it does not cache each types’ public parameterless constructor:

var obj = Activator.CreateInstance(typeof(Xpto)) as Xpto;

Using LINQ expressions

The major drawback of this approach is the time it takes to build the actual code (the first call to Compile). After that, it should be fast:

var ci = typeof(Xpto).GetConstructor(Type.EmptyTypes);<br />var expr = Expression.New(ci);<br />var del = Expression.Lambda(expr).Compile();<br />var obj = del.DynamicInvoke() as Xpto;

Of course, if you are to call this a number of times for the same type, it may be worth caching the constructor for each type.

Using Delegates

The LINQ expressions approach actually compiles to this one, but this is strongly typed:

Func<Xpto> del = () => new Xpto();<br />var obj = del();

Using Roslyn

This one is relatively new in .NET. As you may know, Microsoft now uses Roslyn to both parse and generate code dynamically. The scripting capabilities are made available through the Microsoft.CodeAnalysis.CSharp.Scripting NuGet package. The actual code for instantiating a class (or actually executing any code) dynamically goes like this:

var obj = CSharpScript.EvaluateAsync("new Xpto()").GetAwaiter().GetResult() as Xpto;

Do keep in mind that Roslyn is asynchronous by nature, so you need to wait for the result, also, do add the full namespace of your type, which I omitted for brevity. There are other APIs that allow you to compile code and reuse the compilation:

var script = CSharpScript.Create<Xpto>("new Xpto()", ScriptOptions.Default.AddReferences(typeof(Xpto).Assembly));<br />var runner = script.CreateDelegate();<br />var obj = runner().GetAwaiter().GetResult();

Conclusion

Feel free to run your tests, with a few iterations, and look at the results. Always compare with the normal way to create objects, the new operator. Do not forget the problems with each approach, like the need to cache something or any limitations on the instantiated object.

In my machine, for 1000 iterations, a couple times for the same run, I get these average results (elapsed ticks):

Technique Delay
Direct 0.148
FormatterServices.GetUninitializedObject 0.324
Activator.CreateInstance 0.296
Reflection 0.6
IL 0.557
LINQ Expression 4.085
Delegate 0.109
Roslyn 2400.796

Some of these may be surprising to you, as they were to me! It seems that reflection is not that much slower than direct instantiation as one might think… hmmm…

As usual, I’d love to hear your thoughts on this! More to come soon! Winking smile

C# Special Method Names

Introduction

You may not have realized that some of the patterns that you’ve been using for ages in your C# programs are based on conventions, rather than on a specific API. What I mean by this is, some constructs in C# are based on some magical methods with well-defined names which are not defined in any base class or interface, but yet just work. Let’s see what they are.

Enumerations

You are probably used to iterating through collections using the foreach statement. If you are, you may know that foreach actually wraps a call to a method called GetEnumerator, like the one that is defined by the IEnumerable and IEnumerable<T> interfaces. Thus, you might think, the magic occurs because the collection implements one or the two, but you would be wrong: it turns out that in order to iterate through a class using foreach all it takes is that the class exposes a public method called GetEnumerator that returns either a IEnumerator or a IEnumerator<T> instance. For example, this works:

public class Enumerable
{
    public IEnumerator GetEnumerator()
    {
        yield return 1;
        yield return 2;
        yield return 3;
    }
}

var e = new Enumerable();

foreach (int i in e) { /*...*/ }

As you see, there is no need to implement any of these interfaces, but it is a good practice, for example, because it gives you access to LINQ extension methods.

Deconstruction to Tuples

Tuples were introduce in C# 7. In a nutshell, they provide a way for us to return multiple values from a method:

(int x, int y) GetPosition()
{
    return (x: 10, y: 20);
}

Another option is to have a class deconstructed into a tuple. Say, for example, that we have a class like this:

public class Rectangle
{
    public int Height { get; set; }
    public int Width { get; set; }
}

We can have it deconstructed into a tuple, by providing one or more Deconstruct methods in this class:

public void Deconstruct(out int h, out int w)
{
    h = this.Height;
    w = this.Width;
}

Which allows you to write code like this:

var rectangle = new Rectangle { Height = 10, Width = 20 };
var (h, w) = rectangle;

You can implement multiple Deconstruct methods with different parameters, which must always be out. When you try to assign your class to a tuple, C# will try to find a Deconstruct method that matches the tuple’s declaration, or throw an exception if one cannot be found:

public void Deconstruct(out int perimeter, out int area, out bool square)
{
    perimeter = this.Width * 2 + this.Height * 2;
    area = this.Width * this.Height;
    square = this.Width == this.Height;
}

var (perimeter, area, square) = rectangle;

Collection Initialization

Since C# 6, we have a more concise syntax for initializing collections:

var strings = new List<string> { "A", "B", "C" };

The syntax to follow is an enumeration of items whose type matches the collection’s item type, inside curly braces, each separated by a comma. This is possible because there is a public Add method that takes a parameter of the appropriate type. What happens behind the scene is that the Add method is called multiple times, one for each item inside the curly braces. Meaning, this works too:

public class Collection : IEnumerable
{
    public IEnumerator GetEnumerator() => /* ... */
    public void Add(string s) { /* ... */ }
}

Notice that this collection offers a public Add method and needs to implement either IEnumerable or IEnumerable<T>, which, mind you, do not define an Add method. Having this, we can write:

var col = new Collection { "A", "B", "C" };

The magical Add method can have multiple parameters, like for dictionaries:

var dict = new Dictionary<string, int> { { "A", 1 }, { "B", 2 }, { "C", 3 } };

Each parameter will need to go inside it’s own set of curly braces.

What’s even funnier is, you can mix different Add methods with different parameters:

public void Add(int i) { /* ... */ }
public void Add(string s) { /* ... */ }

var col = new Collection { 1, 2, 3, "a", "b", "c" };

Conclusion

In this post I introduced the magical GetEnumerator, Deconstruct and Add methods. This was just for fun, the information here is probably useless, but, hey, it’s done! Winking smile

Succinctly Books Index

This page lists all the books I wrote or reviewed for Syncfusion’s Succinctly series.

Books I wrote:

Books I reviewed:

Stackify Posts Index

As some of you may remember, last year I started writing occasionally a few posts for Stackify (@Stackify). In this page I will try to keep this list updated.

Stay tuned for more!

Interpose.Core Changes

I’m writing this from the 2018 MVP Global Summit!

Got my first pull request for Interpose.Core: it came from @x2764tech and it was suggested that Interpose should target .NET Standard. For some reason, I had come to the impression that it wasn’t possible – I *had* tried – but now it seems otherwise. Also, I got a heads up that the unit tests were failing for attribute-based interception, and I now fixed it.

Interpose.Core is now at version 1.4.0. Some of the changes were:

  • BUG: fixed interception with attributes where the interception attribute was being applied at the method level, not class
  • IMPROVEMENT: targeting .NET Standard instead of .NET Core
  • IMPROVEMENT: added caching of handler instances
  • IMPROVEMENT: added support for providing a service provider
  • IMPROVEMENT: small fixes here and there

Huge thanks to x2764tech for the contribution! Winking smile

Interpose.Core Updates

Some of you may have read my previous post on Interpose.Core. I’ve made a few modifications since:

  • Added caching for type generators, meaning, you won’t have to generate the same types twice
  • Added DispatchProxy interception; if you don’t know DispatchProxy, it’s .NET Core’s replacement for RealProxy, the transparent proxy mechanism that exists in .NET “full” framework. It may be used as an alternative to interface interception, as we don’t need to generate a type at runtime

The source code is updated and so is the NuGet package. Do have a look and share your thoughts! Winking smile

Introducing Interpose.Core

Update: see this post and this one.

I’m writing this from the 2018 MVP Global Summit!

Some of you may remember a series of posts I wrote about AOP and code interception in .NET. In them I built an AOP framework from scratch that could do custom interception. A few years passed by and I decided to revisit it and turn it into a .NET Core project: I introduce to you Interpose.Core.

Interpose: place or insert between one thing and another.

Interpose is available as an open source project (under Lesser GNU Public License) which you can get from GitHub or NuGet. It can do type and instance interception:

  • Type: virtual methods, the type to intercept cannot be sealed
  • Instance: interface and dynamic interception

Interpose uses Roslyn to generate the proxy types. As it targets .NET Core, you can use it on any supported platform.

At its core, you have an interceptor class (IInstanceInterceptor or ITypeInterceptor) and you ask for an instance or a type to be intercepted using a given handler (instance or type). It then generates a proxy instance (or type, which you must instantiate yourself). When using the generated proxy instance, for the target methods or properties, it will execute the provided handler.

So, what’s an handler like? An handler is just any implementation of the IInterceptionHandler method, that offers a single method, Invoke. This method takes a parameter that describes all of the execution context (target object, target method, parameters). From it, you can run the base implementation before or after performing any actions, or you can skip it altogether, in which case, you must provide a return value yourself.

Two instance interception examples, one for each interceptor, first, interface:

var interceptor = new InterfaceInterceptor();
var instance = new MyType();
var handler = new MyHandler();
var proxy = interceptor.Intercept(instance, typeof(IMyType), handler) as IMyType;

As you can see, you need to explicitly state which interface in the target instance you wish to intercept.

For dynamic, you can do something similar:

var interceptor = new DynamicInterceptor(); var instance = new MyType(); var handler = new MyHandler(); dynamic proxy = interceptor.Intercept(instance, null, handler);

Here you don’t need to specify an interface, but you do need to declare your proxy instance as dynamic.

Types are easy to intercept too, the major difference is that you pass types, not instances:

var interceptor = new VirtualMethodInterceptor();

var proxyType = interceptor.Intercept(typeof(MyType), typeof(MyHandler));

var proxy = Activator.CreateInstance(proxyType) as MyType;

Here the handler must be a public non-abstract class with a public parameterless constructor.

A very simple handler could be:

class MyHandler : IInterceptionHandler

{

public void Invoke(InterceptionArgs args)

{

if (args.Method.ReturnType == typeof(int))

{

//always return 100

args.Result = 100;

}

else

{

Console.Out.WriteLine(“Before base method call”);

args.Proceed();

Console.Out.WriteLine(“After base method call”);

}

}

}

There are a couple of extensions that allow you to use a registry for mapping methods to intercept to handlers or handlers defined as attributes.

You can integrate it with .NET Core’s dependency injection framework:

services.AddInterfaceInterceptor();

services.AddVirtualMethodInterceptor();

services.AddDynamicInterceptor();

Still some features missing, such as caching of generated proxy types, interception of generic types or the ability to maintain custom attributes from the base types or interfaces. Will try to address these when I have the time. Also, might be useful to have a small library of common handlers (logging, exception handling, measuring time, etc), if this ever comes to live, I will do it in a different assembly.

In the meantime, enjoy it and let me know what you think!

ASP.NET Core Pitfalls – Session Storage

Previous versions of ASP.NET featured several ways to persist sessions:

  • InProc: sessions would be stored on the server’s process memory
  • SQL Server: sessions would be serialized and stored in a SQL Server database; other vendors offered similar functionality
  • State Server: sessions would be serialized and stored on an instance of the ASP.NET State Service
  • Custom: we had to implement our own persistence mechanism

InProc was probably the most commonly used; it was the fastest, as the items in the session weren’t serialized, but on the other side they would not survive server crashes. Using this approach things usually worked well, because the session object merely provided a reference to the items stored in memory, so manipulating these items didn’t mandate that the session be explicitly saved.

In ASP.NET Core, all of this is gone. By default, sessions are still stored in memory but one can also use one of the available distributed cache mechanisms. The main difference, however, is that even when the session objects are stored in memory, they still need to be serialized and deserialized prior to persisting or retrieving them. It is no longer possible to just store a pointer to a memory object and keep manipulating it transparently; the object to be stored needs to be converted into a byte array first. You can use any serializer you want.

If we think about it seriously, it was probably a good decision: I’ve seen applications where a lot of data was being stored on the session using InProc mode, but then there was a need to switch to another mode to improve scalability, and the application would just stop working, as the objects being stored weren’t serializable. This time, we need to carefully think about it beforehand.

ASP.NET Core Pitfalls – Redirect to Action Keeps Route Parameters

When you redirect after a POST – following the famous Post-Redirect-Get pattern – but your previous view was constructed using a route parameter, then it will be sent to the redirect action as well.

For example, say you are responding to a request for /Filter/Smartphone, where Smartphone is a route parameter, you POST it to some controller action and at the end you redirect to the Index action using the RedirectToAction method:

return this.RedirectToAction(nameof(Index));

The browser will issue the GET request for Index but keeps the Smartphone route parameter, which is not good.

The solution is to pass a routeValues parameter to RedirectToAction that doesn’t contain any of the possible route parameters. One way to do it would be to create a dictionay with all action parameters nullified:

return this.RedirectToAction(nameof(Index), MethodBase.GetCurrentMethod().GetParameters().ToDictionary(x => x.Name, x => (object) null));

The solution to have this done automatically lies in the MethodBase.GetCurrentMethod() method. This way, you are sure to avoid any unwanted route parameters on your next request.

In case you are wondering, passing null, a dictionary without entries or object won’t work, the only other way is to pass an anonymous value with the parameters explicitly set to null.