Controller versus view in MVC .net: is the code in the view as fast as that in the controller? Is it slower?

One of the basic rules of MVC is that views should be only – exactly – views, that is to say: objects that present to the user something that is already “worked and calculated”.

They should perform little, if not none at all, calculation. All the significant code should be in the controllers. This allows better testability and maintainability.

Is this, in Microsoft’s interpretation of MVC, also justified by performance?

We tested this with a very simple code that does this:

– creates 200000 “cat” objects and adds them to a List

– creates 200000 “owner” objects and adds them to a List

– creates 200000 “catowner” objects (the MTM relation among cats and owners) and adds them to a List

– navigates through each cat, finds his/her owner, removes the owner from the list of owners (we don’t know if cats really wanted this, but their freedom on code fits our purposes).

We’ve run this code in a controller and in a razor view.

The result seem to suggest that the code in views runs just as fast as in controllers even if don’t pre-compile views (the compilation time in our test is negligible).

The average result for the code with the logic in the controller is 18.261 seconds.

The average result for the code with the logic in the view is 18.621 seconds.

The performance seems therefore very similar.

Here is how we got to this result.

Case 1: Calculations are in the CONTROLLER

Models:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebPageTest.Models
{
public class Owner
{
public string Name { get; set; }
public DateTime DOB { get; set; }
public virtual CatOwner CatOwner { get; set; }
}
public class Cat
{
public string Name { get; set; }
public DateTime DOB { get; set; }
public virtual CatOwner CatOwner { get; set; }
}
public class CatOwner
{
public virtual Cat Cat { get; set; }
public virtual Owner Owner { get; set; }
}
}

Controller:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebPageTest.Models;

namespace WebPageTest.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
Stopwatch howLongWillItTake = new Stopwatch();
howLongWillItTake.Start();
List<Owner> allOwners = new List<Owner>();
List<Cat> allCats = new List<Cat>();
List<CatOwner> allCatOwners = new List<CatOwner>();
// create lists with 200000 cats, 200000 owners, 200000 relations
for (int i = 0; i < 200000; i++)
{
//Cat
Cat CatX = new Cat();
CatX.Name = “Cat ” + i.ToString();
CatX.DOB = DateTime.Now.AddDays(i / 10);
//Owner
Owner OwnerX = new Owner();
OwnerX.Name = “Owner ” + i.ToString();
OwnerX.DOB = DateTime.Now.AddDays(-i / 10);
//Relationship “table”
CatOwner CatOwnerXX = new CatOwner();
CatOwnerXX.Cat = CatX;
// Relations
CatOwnerXX.Owner = OwnerX;
CatX.CatOwner = CatOwnerXX;
OwnerX.CatOwner = CatOwnerXX;
//add to list
allCats.Add(CatX);
allOwners.Add(OwnerX);
allCatOwners.Add(CatOwnerXX);
}
// now I remove all the items
foreach (Cat CatToDelete in allCats)
{
Owner OwnerToRemove = CatToDelete.CatOwner.Owner;
allOwners.Remove(OwnerToRemove);
}
// now all cats are free
int numberOfCats = allCats.Count();
int numberOfOwners = allOwners.Count();
howLongWillItTake.Stop();
long elapsedTime = howLongWillItTake.ElapsedMilliseconds;
// give info to the view
ViewBag.numberOfCats = numberOfCats;
ViewBag.numberOfOwners = numberOfOwners;
ViewBag.elapsedTime = elapsedTime;
return View();
}
}
}

View:

<div class=”row”>
<div class=”col-md-12″>
<hr />
<b>Results</b>
<br/>
Cats: @ViewBag.numberOfCats
<br/>
Owners: @ViewBag.numberOfOwners
<br/>
ElapsedTime in milliseconds: @ViewBag.ElapsedTime
<hr />
</div>
</div>

Case 2: Calculations are in the VIEW (pre-compiled)

Models: same as above

Controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebPageTest.Controllers
{
public class HomeBisController : Controller
{
public ActionResult Index()
{
return View();
}
}
}

View:

@using System;
@using System.Collections.Generic;
@using System.Diagnostics;
@using System.Linq;
@using System.Web;
@using WebPageTest.Models;
@using System.Web.Mvc;
@{
Stopwatch howLongWillItTake = new Stopwatch();
howLongWillItTake.Start();
List<Owner> allOwners = new List<Owner>();
List<Cat> allCats = new List<Cat>();
List<CatOwner> allCatOwners = new List<CatOwner>();
//create lists with 200000 cats, 200000 owners, 200000 relations
for (int i = 0; i < 200000; i++)
{
//Cat
Cat CatX = new Cat();
CatX.Name = “Cat ” + i.ToString();
CatX.DOB = DateTime.Now.AddDays(i / 10);
//Owner
Owner OwnerX = new Owner();
OwnerX.Name = “Owner ” + i.ToString();
OwnerX.DOB = DateTime.Now.AddDays(-i / 10);
//Relationship “table”
CatOwner CatOwnerXX = new CatOwner();
CatOwnerXX.Cat = CatX;
// Relations
CatOwnerXX.Owner = OwnerX;
CatX.CatOwner = CatOwnerXX;
OwnerX.CatOwner = CatOwnerXX;
//add to list
allCats.Add(CatX);
allOwners.Add(OwnerX);
allCatOwners.Add(CatOwnerXX);
}
// now I remove all the items
foreach (Cat CatToDelete in allCats)
{
Owner OwnerToRemove = CatToDelete.CatOwner.Owner;
allOwners.Remove(OwnerToRemove);
}
// now all cats are free
int numberOfCats = allCats.Count();
int numberOfOwners = allOwners.Count();
howLongWillItTake.Stop();
long elapsedTime = howLongWillItTake.ElapsedMilliseconds;
// give info to the view

}
<div class=”row”>
<div class=”col-md-12″>
<hr />
<b>Results</b>
<br />
Cats: @numberOfCats
<br />
Owners: @numberOfOwners
<br />
ElapsedTime in milliseconds: @elapsedTime
<hr />
</div>
</div>

C# 5 polymorphism notes: interface implementations at subclass level

When we want to show how polymorphism works, we often use the superclass -> subclass example and verify how overridden methods of the subclass are dynamically invoked when the subclass is created using the superclass’s type (in this fashion: SuperClassType x = new SubClassType() )

Here I would like to show something a bit different: how dynamic invocation of methods works when we create objects using the type of an interface they implement, and what changes if the subclasses inherit from a superclass and implement the interface itself.

The interface and objects we’ll use are very simple.

We have an interface called IAreaOrVolume, which contains a “blueprint” method AreaOrVolumeSize.

We have a “Quad” class that implements this interface.

Quad gives back the Area by multiplying its own width by its own height.

Then, we have a PossibleSquare that subclasses Quad. We call it “PossibleSquare” because we will see that, given the inheritance mechanisms, at times it is a Square but works as a Quad.

We have a PossibleCube that subclasses PossibleSquare. We call it “PossibleCube” because it is a Cube BUT its volume is at times (we will see exactly when) calculated as a Square’s or even any Quad’s area. Probably the idea that a “Cube” is a subclass of a “Square” is logically flawed, as a Square is a “slice” of a Cube, but for the time let us forget about the Aristotelic Ideas and let us see just what they mean in C#.

All objects have a constructor that accepts width, height and depth. Even if a Square does not have a height different from its width, we pass the constructor a width different from the height to show how unexpected results can stem from different implementations of inheritance.

In this first example, the “AreaOrVolumeSize” method is declared as “virtual” in the superclass “Quad” and overridden in the subclasses. See, in bold, the modifiers “virtual” and “override”.

namespace TestInheritanceWithInterfaces
{

interface IAreaOrVolume
{
double AreaOrVolumeSize();
//whatever object implements this interface will have to define its own AreaOrVolumeSize metod
}

class Quad : IAreaOrVolume
{
protected double _width;
protected double _height;
protected double _depth;

public Quad(double width, double height, double depth)
{
_width = width;
_height = height;
_depth = depth;

}

public virtual double AreaOrVolumeSize() // virtual means: go on, you can override me
{
return _width * _height * 1;
// this is a Quad. In calculating “Area or Volume”, we disregard the depth of the object, as a Quad has an area, not a volume
}

}

class PossibleSquare : Quad
{
public PossibleSquare(double width, double height, double depth) : base(width, height, depth) { }

public override double AreaOrVolumeSize()
{
return _width * _width * 1;
// this is a Square. In calculating “Area or Volume”, we disregard the depth of the object,
// as a Square has an area, not a volume
// we also disregard the height as it is equal to the width
}
}

class PossibleCube : PossibleSquare
{
public PossibleCube(double width, double height, double depth) : base(width, height, depth) { }

public override double AreaOrVolumeSize()
{
return _width * _width * _width;
// this is a Cube.
// In calculating the volume, we disregard depth and height as they are both equal to the width
}
}

class Program
{
static void Main(string[] args)
{
IAreaOrVolume thisShape;
// typing our variable with the interface implemented by classes and subclasses allows
// polymorphism

thisShape = new Quad(5,6,1);
Debug.WriteLine(“Shape’s area or volume: {0}”,thisShape.AreaOrVolumeSize());

thisShape = new PossibleSquare(5,6,1);
Debug.WriteLine(“Shape’s area or volume: {0}”, thisShape.AreaOrVolumeSize());

thisShape = new PossibleCube (5,6,2);
Debug.WriteLine(“Shape’s area or volume: {0}”, thisShape.AreaOrVolumeSize());
}

}

}

The results are what we expected:

Quad’s area or volume: 30
Square’s area or volume: 25 (height is ignored in the overridden method; the area is a Square’s area = width squared)
Cubes’s area or volume: 125 (height is ignored in the overridden method; volume is the cube’s volume = width to the power of three)

What happens, instead, if we declare the AreaOrVolumeSize as “new” methods, which do not inherit from their superclass?

In this following example, the AreaOrVolumeSize method is not overridden, but marked as “new” suggesting that we want to hide the superclass’s method.

namespace TestInheritanceWithInterfaces
{

interface IAreaOrVolume
{
double AreaOrVolumeSize();
//whatever object implements this interface will have to define its own AreaOrVolumeSize metod
}

class Quad : IAreaOrVolume
{
protected double _width;
protected double _height;
protected double _depth;

public Quad(double width, double height, double depth)
{
_width = width;
_height = height;
_depth = depth;

}

public double AreaOrVolumeSize()
{
return _width * _height * 1;
// this is a Quad. We disregard the depth of the object, as a Quad has an area, not a volume
}

}

class PossibleSquare : Quad
{
public PossibleSquare(double width, double height, double depth) : base(width, height, depth) { }

public new double AreaOrVolumeSize() // new hides the superclass’s implementation
{
return _width * _width * 1;
// this is a Square. We disregard the depth of the object,
// as a Square has an area, not a volume
// we also disregard the height as it is equal to the width
}
}

class PossibleCube : PossibleSquare
{
public PossibleCube(double width, double height, double depth) : base(width, height, depth) { }

public new double AreaOrVolumeSize()
{
return _width * _width * _width;
// this is a Cube.
// we disregard depth and height as they are both equal to the width
}
}

class Program
{
static void Main(string[] args)
{
IAreaOrVolume thisShape;
// typing our variable with the interface implemented by classes and subclasses allows
// polymorphism

thisShape = new Quad(5,6,1);
Debug.WriteLine(“Quad’s area or volume: {0}”,thisShape.AreaOrVolumeSize());

thisShape = new PossibleSquare(5,6,1);
Debug.WriteLine(“Square’s area or volume: {0}”, thisShape.AreaOrVolumeSize());

thisShape = new PossibleCube (5,6,2);
Debug.WriteLine(“Cubes’s area or volume: {0}”, thisShape.AreaOrVolumeSize());
}
}
}

The result is what we expected, and a bit funny:

Quad’s area or volume: 30
Square’s area or volume: 30
Cubes’s area or volume: 30

What happened here is: since we declared the AreaOrVolumeSize as new in the subclasses, C# supposes we want to break the polymorphism mechanism and invoke the method of the superclass, not the “new” implementation in the subclass.

There is another possibility, though: if our subclasses implement the interface along with inheriting from the superclass, the runtime behavior is again that of invoking the specific class’s implementation, not the superclass’s.

In the following code, our subclasses (PossibleSquare and PossibleCube) inherit from Quad and they hide its AreaOrVolumeSize method, but they also implement the interface directly. In this way, even if they have hidden the superclass’s method, .Net knows that it is their method implementation it has to call, not the superclass’s:

namespace TestInheritanceWithInterfaces

{

interface IAreaOrVolume
{
double AreaOrVolumeSize();
//whatever object implements this interface will have to define its own AreaOrVolumeSize metod
}

class Quad : IAreaOrVolume
{
protected double _width;
protected double _height;
protected double _depth;

public Quad(double width, double height, double depth)
{
_width = width;
_height = height;
_depth = depth;

}

public double AreaOrVolumeSize()
{
return _width * _height * 1;
// this is a Quad. We disregard the depth of the object, as a Quad has an area, not a volume
}

}

class PossibleSquare : Quad, IAreaOrVolume // implementing directly IAreaOrVolume
{
public PossibleSquare(double width, double height, double depth) : base(width, height, depth) { }

public new double AreaOrVolumeSize()
{
return _width * _width * 1;
// this is a Square. We disregard the depth of the object,
// as a Square has an area, not a volume
// we also disregard the height as it is equal to the width
}
}

class PossibleCube : PossibleSquare, IAreaOrVolume // implementing directly IAreaOrVolume
{
public PossibleCube(double width, double height, double depth) : base(width, height, depth) { }

public new double AreaOrVolumeSize()
{
return _width * _width * _width;
// this is a Cube.
// we disregard depth and height as they are both equal to the width
}
}

class Program
{
static void Main(string[] args)
{
IAreaOrVolume thisShape;
// typing our variable with the interface implemented by classes and subclasses allows
// polymorphism

thisShape = new Quad(5,6,1);
Debug.WriteLine(“Quad’s area or volume: {0}”,thisShape.AreaOrVolumeSize());

thisShape = new PossibleSquare(5,6,1);
Debug.WriteLine(“Square’s area or volume: {0}”, thisShape.AreaOrVolumeSize());

thisShape = new PossibleCube (5,6,2);
Debug.WriteLine(“Cubes’s area or volume: {0}”, thisShape.AreaOrVolumeSize());
}
}
}

The result?

This time, more logic:

Quad’s area or volume: 30
Square’s area or volume: 25
Cubes’s area or volume: 125

Alternatives:

Below, we declare PossibleCube as a subclass of PossibleSquare, but do not specify it implements IAreaOrVolume.

class PossibleCube : PossibleSquare // NOT implementing directly IAreaOrVolume

Result?

Quad’s area or volume: 30
Square’s area or volume: 25 (its own implementation)
Cubes’s area or volume: 25 (again, the superclass’s implementation)

Here below, instead, it is PossibleSquare that hides the method’s implementation, and does not implement the interface directly

class PossibleSquare : Quad // NOT implementing directly IAreaOrVolume

class PossibleCube : PossibleSquare, IAreaOrVolume // again implementing directly IAreaOrVolume

The obvious result:

Quad’s area or volume: 30
Square’s area or volume: 30 (again, the superclass’s implementation)
Cubes’s area or volume: 125 (its own implementation)