none
Poor startup performance of Entity Framework RRS feed

  • Question

  • Hello,

    We are looking at using Entity Framework 4.3 Code First as the data layer of our web application. The application currently has 350 entities with only some of the relationships between them defined. Currently the first request to get data takes over 30 seconds. All this does is

    1. Create the dbcontext

    2. Call Set<T> on the context

    3. Run Count() on the dbset (The database table in this intance only has 4 records).

    I used the EF Power tools to generate views but this only reduced the startup time by 0.5 of a second. Our final product will have over 800 entities. Once these are added I expect the start up time will be well over a minute. 

    Is the Entity Framework not suitable for such a system or is there anything else I can try to improve the startup time?

    Thanks,

    Harsha

    Wednesday, April 18, 2012 9:59 AM

Answers

  • Hello Harsha

    We had a very similar problem which I was tearing my hair out over.  It nearly caused me to abandon EF altogether.  However, I found this post from Scott Guthrie describing the auto start mechanisms that have been built into IIS 7.5 (so ... Windows 7 and Windows Server 2008 R2 and later).  Put simply, this allows you to specify some code that runs in your web application before it starts to accept requests.  Aside from running at the time IIS starts, it also runs when a worker process is recycled ... and the old worker process isn't killed until the new one is ready to accept requests.  Magic!  Of course, if you're not running IIS 7.5, or you don't have access to applicationHost.config to set this up, this might not be an option for you.

    Here's what I have in my warmup class.  Essentially, it constructs a few services that cache info from the database for later use.  You could do whatever you want in there.

        public class WarmUp : IProcessHostPreloadClient
        {
            public void Preload(string[] parameters)
            {
                try
                {
                    var languageService = DependencyResolver.Current.GetService<ILanguageService>();
                    var globalizationService = DependencyResolver.Current.GetService<IGlobalizationService>();
                    var configurationService = DependencyResolver.Current.GetService<IConfigurationService>();
                   }
                }
                catch (Exception)
                {
                    /* Ignore so we don't hold up the web load */
                }
            }
        }
    

    Hope that helps

    Adrian

    Wednesday, April 18, 2012 3:12 PM
  • Hello Adrian,

    Thanks for the tip. We will definitely use the auto start feature in the situations where we control the web server.

    Harsha

    Thursday, April 19, 2012 11:48 AM

All replies

  • After posting this I had a thought and set my database initializer to null. This has brought the start up time down to 18 seconds. During initialisation it makes a couple of queries to the database that take hardly anytime at all. On the client side the process maxes out the CPU for 18 seconds. Does anybody know why the precompiled views have not had any impact on the performance? The following link suggests it should make a significant impact

    Squash Entity Framework Start Time

    Wednesday, April 18, 2012 10:50 AM
  • Hi HarshaP,

    Try placing a break point in the constructor of the view or the GetViewAt() method to make sure the pre-generated views are being used. I recently had to troubleshoot a similar situation. We have a little over 300 entities and the first query was taking about 24 seconds. I found that the views weren't being used at all. After some fairly exhaustive troubleshooting I found that the issue was due to having the POCO entities defined in a separate assembly. I had placed the views in the same assembly as the context. After moving them to the POCO entities' assembly the problem was resolved and the time for the first query was reduced to about 1.5 seconds. 

    Regards,

    Tyler

    Wednesday, April 18, 2012 1:11 PM
  • On 4/18/2012 5:59 AM, HarshaP wrote:
    > Hello,
    >
    > We are looking at using Entity Framework 4.3 Code First as the data
    > layer of our web application. The application currently has 350 entities
    > with only some of the relationships between them defined. Currently the
    > first request to get data takes over 30 seconds. All this does is
    >
    > 1. Create the dbcontext
    >
    > 2. Call Set<T> on the context
    >
    > 3. Run Count() on the dbset (The database table in this intance only has
    > 4 records).
    >
    > I used the EF Power tools to generate views but this only reduced the
    > startup time by 0.5 of a second. Our final product will have over 800
    > entities. Once these are added I expect the start up time will be well
    > over a minute.
    >
    > Is the Entity Framework not suitable for such a system or is there
    > anything else I can try to improve the startup time?
    >
     
    I replied to a guy that was using the model first approach that had over
    500 or more entities on the model. He did the compiled views on the
    model that took the time from a minute to down to a couple of seconds on
    first access or startup usage by an application.
     
    Maybe you should test the model first approach with putting the tables
    on the model and using compiled views.
     
     
    It doesn't look like the code first approach is viable if looking for
    speed on the startup.
     
    Wednesday, April 18, 2012 2:29 PM
  • Hello Tyler,

    Thanks for your reply. The pre generated views are definitely being called after I moved the class into the same assembly as the POCO entities. The views class gets created twice and calls are made to the GetViewAt method.

    Regards,

    Harsha

    Wednesday, April 18, 2012 2:42 PM
  • Hello Arnold,

    Thanks for your reply. I will write a test program to check the performance with the model first approach. Presumably the same would apply to the database first approach? Do you know why the compiled views in the code first approach are slower than those of the model first/database first?

    Regards,

    Harsha

    Wednesday, April 18, 2012 2:49 PM
  • I don't know the answer to your question as to the difference between
    compiled views against the model as opposed to against the database. The
    the model and see what happens.
     
    Wednesday, April 18, 2012 3:04 PM
  • Hello Harsha

    We had a very similar problem which I was tearing my hair out over.  It nearly caused me to abandon EF altogether.  However, I found this post from Scott Guthrie describing the auto start mechanisms that have been built into IIS 7.5 (so ... Windows 7 and Windows Server 2008 R2 and later).  Put simply, this allows you to specify some code that runs in your web application before it starts to accept requests.  Aside from running at the time IIS starts, it also runs when a worker process is recycled ... and the old worker process isn't killed until the new one is ready to accept requests.  Magic!  Of course, if you're not running IIS 7.5, or you don't have access to applicationHost.config to set this up, this might not be an option for you.

    Here's what I have in my warmup class.  Essentially, it constructs a few services that cache info from the database for later use.  You could do whatever you want in there.

        public class WarmUp : IProcessHostPreloadClient
        {
            public void Preload(string[] parameters)
            {
                try
                {
                    var languageService = DependencyResolver.Current.GetService<ILanguageService>();
                    var globalizationService = DependencyResolver.Current.GetService<IGlobalizationService>();
                    var configurationService = DependencyResolver.Current.GetService<IConfigurationService>();
                   }
                }
                catch (Exception)
                {
                    /* Ignore so we don't hold up the web load */
                }
            }
        }
    

    Hope that helps

    Adrian

    Wednesday, April 18, 2012 3:12 PM
  • Hello Adrian,

    Thanks for the tip. We will definitely use the auto start feature in the situations where we control the web server.

    Harsha

    Thursday, April 19, 2012 11:48 AM
  • Hello  All,

    I've tested the startup performance using all the EF approaches and have got the following results

    Database First - 3 seconds

    Model First - 3 seconds

    Code First - 18 seconds

    The times posted by db/model first were better than I expected.

    I then generated the pre compiled views for all three approaches (using edmgen for db/model first and the entity framework power tools for code first). Surprisingly, I see no performance difference at all with the views. In all instances the view class gets created and the GetViewAt method gets called multiple times (I think it gets called once for each view)

    I would really like to stick with the code first approach as I want the domain objects layer to be completely independent of the Entity Framework. Does anybody have any thoughts/ideas on improving the performance of code first? We can mitigate the performance impact in production using Adrian's suggestion (ASP.NET auto start). However this is going to be a real pain in development.

    Harsha

    Thursday, April 19, 2012 12:11 PM
  •  
    Well from what I have done with using the EF Model first approach in
    n-tier, a Data Transfer Object is used,  and the EF entity is left at
    the DAL. The DTO(s) are what go through the tiers with the DTO(s) being
    an abstraction away from the model.
     
    Thursday, April 19, 2012 3:09 PM