Little update on my post -- again, specific to my use case, but perhaps a worthy demonstration:
sproaty wrote:I'm looking into reducing the memory footprint of my site, too (veering off quite drastically from the Nop.Web site) and am looking into potentially reducing caching for many services, as with the way I'm writing the code then there won't be more than 1 call to the same service. Instead I'm creating more granular service methods that do joins across entities needed and returns fully-populated domain objects, so no need to eager load.
Also for some pages I know will be traffic heavy and performance crucial, I'm changing custom service methods to return "skinny" objects, that I can use with automapper to map to ViewModels. If you look at a query generated in retrieving a Product, then it's bringing back ~40 columns, whereas I'm only using 6 or so. So at the service layer I'm projecting to a SkinnyProduct class that contains only what I need -- simplifies my code's intention when using the service, and also minimises the data that needs to fetched from the DB.
May knock a few mb from usage.
I went ahead and implemented these "Skinny" classes inside my service for retrieving products for "catalog" page and ran a few performance tests (refreshed page first to warm cache, then refresh 5 times and check query time using Glimpe's EF Profiler" tab:
: (service method I'm using instead of "SearchProducts". Total LINQ query; it does far less query checks than the above mentioned stored procedure call; and also eagerly loads every product's manufacturer (which I've changed to be a Product has one manufacturer instead of product has many)
Using SearchProducts at first took about 250ms, and then n* calls to retrieve the Manufacturer as eager loading isn't possible through the stored procedure way. So then, one query + 15x 2ms queries to show 15 products.
Then added another service method which eagerly loads manufacturers - took about 95ms on average. Returning
Before, returning a IEnumerable<Product>
Then I created a few "Skinny" classes for Product + Manufacturer and project my LINQ objects to these objects, instead of the "full-blown" domain models, seeing as I don't use all the Product information here.
This change brough the method call down to 20ms on average. Now my pages are getting ridiculously quick -- ~200ms for the first time load and then down to 50ms as generated links are cached. Awesome!!
I've yet to check how this has affected memory usage; though I suspect by not much.