Reputation: 5529
I use a foreach
in my View to loop over my strongly-typed Model and display a table. With only 25 rows and 7 columns, it takes about 280 msec. This seems slow. Is there some performance trick I should know for using loops in Views?
EDIT: My Controller takes data from an Azure Table and feeds it to a View using a ViewModel pattern. I don't know if this matters, but my Views are in VB and my Models are in C#. So, they're in separate projects. I'll come up with a slimmed down example to post, but I'm running out the door now and will have to get to this later this evening. I was hoping I'd catch the StackOverflow crowd before people went home for the weekend, so my original post was made quickly without example code.
EDIT: I confirmed with Fiddler that there's no lazy loading happening. There's no Fiddler activity during the rendering of the View.
EDIT: If I feed a View with data from an Azure table, it takes 280 msec. If I feed the same View with fake data that looks just like real data from an Azure table, it takes 60 msec. In either case, the Controller just populates a ViewModel object and passes it to the View. The same ViewModel class is used in both instances. I don't get it.
EDIT: I think I figured it out. Perhaps this would have been obvious to everyone else if I had included code at first. Here's my ViewModel:
public class EmployeeChildrenViewModel
{
public Employee employee;
public IEnumerable<Child> children;
}
If I pass the above ViewModel to my View, the foreach
takes 280 msec. If I populate the above ViewModel with children.ToList()
first, then the View only takes 60 msec. However, upon further investigation I see that the overall page load time is the same in either case. I guess it doesn't matter if the IEnumerable is iterated over in my Controller or my View since the overall effect is the same. I'm still not sure what iterating over children
does since I know for sure that it's not hitting the database at that point, as confirmed with Fiddler.
Upvotes: 1
Views: 4395
Reputation: 16513
Are you using Linq-to-SQL or some other ORM that by default loads lazily?
I suggest logging all database calls (datacontext.Log
= some class that inherits from TextWriter
) and check if associations are being loaded lazily when you iterate over them in the View.
EDIT: It appears the below information is not relevant to this question, but I'll leave it here as it might be useful to someone:
Gonna assume you're using Linq-to-SQL here (I'll edit this if this is not the case):
When your model foo has an association Bar (so foo.Bar) and you don't specify any LoadOptions in the datacontext, the Bar is loaded lazily (so: loaded when called, like probably happens in your View) which means the View essentially goes to the database. And this happens for every row.
Do something like the following:
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Foo>(f => f.Bar);
context.LoadOptions = options;
Further, to prevent this, try wrapping your DataContext in a using
statement:
using(DataContext context = new DataContext())
{
}
Your View will now generate an exception when some association is loaded lazily because the DataContext will be disposed by now and unavailable for database operations.
Upvotes: 4
Reputation: 15709
get .NET 4.0 beta and VS 2010 beta, and use
Parallel.Foreach()
Edit: the above answer was supposed to be slightly sarcastic. Although it's not a true solution, once you reap the benefits of the TPL in VS 2010, you'll see what I mean.
In reality, what are you looping over, and what are you doing in your loop exactly, it really depends on your code structure, your data structures, etc. Need more information for a less-sarcastic answer than the above.
Upvotes: 0
Reputation: 31842
Does it really happen only in view? Maybe during iteration You perform database loading which slows whole process down. Do You have some kind of lazy loading implemented? You should check database activity during that process.
Upvotes: 0