Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slow DisplayFor performance in ASP.NET Core MVC

In my current application I'm generating a fairly lengthy table to display to the user. I've been seeing some serious performance issues with it, which I've tracked down to usage of @Html.DisplayFor, and I'm not entirely sure why.

Edit: I've replaced the code sample with a more concise and reproducible setup.

In order to isolate the issue, I have created a new asp.net core MVC project using all default settings in visual studio, with no authentication. I created a view model as such:

public class TestingViewModel
{
    public int Id { get; set; }
    public string TextValue1 { get; set; }
    public string TextValue2 { get; set; }
}

Then added a controller which fills the view model with data to pass to the view:

    public IActionResult TestThings()
    {
        var list = new List<TestingViewModel>();
        for(var i = 0; i < 1000; i++)
            list.Add(new TestingViewModel {Id = i, TextValue1 = "Test", TextValue2 = "Test2"});

        return View(list);
    }

The view is the bare minimum possible to display the data:

@model List<DisplayForTest.ViewModels.TestingViewModel>

@foreach (var item in Model)
{
    @Html.DisplayFor(m => item.Id)
    @Html.DisplayFor(m => item.TextValue1)
    @Html.DisplayFor(m => item.TextValue2)
}

When running this code, it takes over one second to run! The culprit is the DisplayFor. If I change the view as follows:

@model List<DisplayForTest.ViewModels.TestingViewModel>

@foreach (var item in Model)
{
    @item.Id
    @item.TextValue1
    @item.TextValue2
}

This renders in 13ms. It's clear DisplayFor is adding a huge amount of time to rendering... on my PC that's nearly 0.4ms per call. While that's not bad in isolation, it makes it a pretty bad choice for lists or other things.

Is DisplayFor really just that slow? Or am I using it incorrectly?

like image 645
Doddler Avatar asked Oct 13 '16 18:10

Doddler


2 Answers

Is DisplayFor really just that slow? Or am I using it incorrectly?

It takes a bit of overhead to evaluate and execute lambda expressions. First the framework has to validate it, then evaluate it. I am speculating a bit here, but it seems likely this is where the performance concerns are coming from; both of these methods require reflection.

All of the other display methods I've played with (ValueFor, DisplayTextFor, etc.) have the same performance effect in your example.

I can't speak for the MVC team as to why it is used for the default scaffolding, but it does make sense to me. DisplayFor can handle both of the most common use cases (displaying the value of a property, and displaying the value of a property using a custom template), and performs reasonably well in most cases.

In this case, I don't see a problem with just using the raw value (basically .ToStringing it), or using it within an Html.Encode/Html.Raw method depending on what you're looking for.

like image 150
Will Ray Avatar answered Oct 27 '22 08:10

Will Ray


Using .Net Core on a Raspberry PI, I experienced the same problem. The performance went really bad. I used dotTrace and found that the reflection uses much of the time.

Based on the following article, I was able to speedup the application.

like image 3
Michael Mittermair Avatar answered Oct 27 '22 10:10

Michael Mittermair