Using DotProfiler I can see that this particular piece of code is taking around 6.3 seconds to run. As I am using TypedMedia I thought this would be much quicker as it would be accessing the XML cache. Is there a better way of writing this??
The website does have a lot of media items but not a silly amount probably around 500-1000 children that would be returned and I can confirm that the Examine index is working correctly.
I ran into a similar problem on a page with about 300 calls to TypedMedia. On my dev machine with an SSD and a ton of CPU/RAM, it was taking about 5-10 seconds for the page to load. On production, it was taking about 1-2 seconds to load (faster because it was in IIS and wasn't in debug mode, I imagine). My workaround was to create an in-memory cache of media, which is what I'd recommend you do.
The problem is that TypedMedia uses Examine, which is based off of the file system. While it is "fast" by some measures, it is much slower than it could be. Also, TypedMedia will fallback to a database lookup if it can't find everything it needs in the Examine index. To avoid database hits, you can rebuild your examine indexes in the "Developer" section of Umbraco (there is a tab for Examine that has some tools to rebuild indexes).
Great idea with caching media items in cache.
Also it might be usefull to cache all partial view with media items via .CachedPartial or something like that.
My caches didn't store relationships though, so you might want to create a somewhat different cache if you'd like to store parent/child media relationships.
On a different note, but related to media, I have the following code that creates some folders when a member type of School is created. It adds a school folder under the vacancies area and then adds a Live, Pending and Closed folder under that school.
Can you seen any reason why the creation of the four folders would take so long to complete??
void MemberService_Saving(IMemberService sender, SaveEventArgs<IMember> e)
{
var _contentService = Umbraco.Core.ApplicationContext.Current.Services.ContentService;
var _mediaService = Umbraco.Core.ApplicationContext.Current.Services.MediaService;
UmbracoHelper helper = new UmbracoHelper(UmbracoContext.Current);
if (e.SavedEntities != null)
{
foreach (var node in e.SavedEntities)
{
if ((node.ContentType.Alias == "School") && (node.IsApproved) && (!node.Name.Contains("@")) && !node.IsNewEntity())
{
if (String.IsNullOrEmpty(node.RawPasswordValue) && (node.Name != node.Username))
{
try
{
// determine if the member has already been authorised previously (N.B. tests to see if school has already been created in Vacancies area)
var exists = helper.ContentAtXPath("//VacancySchool[@urlName='" + node.Name.ToUrlSegment() + "']");
if (exists.Count() == 0)
{
// find letter that school should be created under in Vacancies area
var parent = helper.ContentSingleAtXPath("//VacancyFolderLetter[@nodeName = '" + node.Name[0].ToString().ToUpper() + "']");
int parentid = parent.Id;
// create school in vacancies area under correct letter
var school = _contentService.CreateContent(node.Name, parentid, "VacancySchool");
school.SetValue("pageHeading", node.Name);
_contentService.SaveAndPublishWithStatus(school);
// create live vacancy folder under school
var live = _contentService.CreateContent("Live", school.Id, "VacancyStatus");
live.SetValue("pageHeading", "Live");
_contentService.SaveAndPublishWithStatus(live);
// create pending vacancy folder under school
var pending = _contentService.CreateContent("Pending", school.Id, "VacancyStatus");
pending.SetValue("pageHeading", "Pending");
_contentService.SaveAndPublishWithStatus(pending);
// create closed vacancy folder under school
var closed = _contentService.CreateContent("Closed", school.Id, "VacancyStatus");
closed.SetValue("pageHeading", "Closed");
_contentService.SaveAndPublishWithStatus(closed);
// create media folder for school under the files/schools folder
var schoolmediafolder = _mediaService.GetById(Convert.ToInt32(ConfigurationManager.AppSettings["SchoolMediaFolderRootNodeId"]));
var newschoolmedia = _mediaService.CreateMedia(node.Name, schoolmediafolder.Id, "Folder");
_mediaService.Save(newschoolmedia);
// create media folder for school under the files/vacancies folder
var vacanciesmediafolder = _mediaService.GetById(Convert.ToInt32(ConfigurationManager.AppSettings["VacanciesMediaFolderRootNodeId"]));
var newvacancymedia = _mediaService.CreateMedia(node.Name, vacanciesmediafolder.Id, "Folder");
_mediaService.Save(newvacancymedia);
// create media folder for school under the images/schools folder
var schoolimagesfolder = _mediaService.GetById(Convert.ToInt32(ConfigurationManager.AppSettings["SchoolImagesFolderRootNodeId"]));
var newschoolimages = _mediaService.CreateMedia(node.Name, schoolimagesfolder.Id, "Folder");
_mediaService.Save(newschoolimages);
}
}
catch (Exception)
{
}
}
}
}
}
}
Umbraco.TypedMedia slow
Can anyone see any problem with the following piece of code??
Using DotProfiler I can see that this particular piece of code is taking around 6.3 seconds to run. As I am using TypedMedia I thought this would be much quicker as it would be accessing the XML cache. Is there a better way of writing this??
Hi Graham,
Do you have a lot of media ?
This code compare all child names with your.
.Children() .Where(x => x.Name == username);
Also can you check that Examine index is working properly.
Thanks
Hi Alex,
The website does have a lot of media items but not a silly amount probably around 500-1000 children that would be returned and I can confirm that the Examine index is working correctly.
Is there a faster way of doing the same task?
Thanks.
Graham, Umbraco.TypedMedia is the fastest way.
As said Shannon Deminick at this topic - https://our.umbraco.org/forum/umbraco-7/using-umbraco-7/74560-querying-umbraco-for-a-specific-media-node-best-practise
So if everything is ok with your index, problem is with query.
The fastest way will be to connect member with media folder, with picker maybe on member level.
Best, Alex
I ran into a similar problem on a page with about 300 calls to
TypedMedia
. On my dev machine with an SSD and a ton of CPU/RAM, it was taking about 5-10 seconds for the page to load. On production, it was taking about 1-2 seconds to load (faster because it was in IIS and wasn't in debug mode, I imagine). My workaround was to create an in-memory cache of media, which is what I'd recommend you do.The problem is that
TypedMedia
uses Examine, which is based off of the file system. While it is "fast" by some measures, it is much slower than it could be. Also,TypedMedia
will fallback to a database lookup if it can't find everything it needs in the Examine index. To avoid database hits, you can rebuild your examine indexes in the "Developer" section of Umbraco (there is a tab for Examine that has some tools to rebuild indexes).You might want to vote on this issue if you'd like to see the media operations improved: http://issues.umbraco.org/issue/U4-6064
Hi Nichilas,
Great idea with caching media items in cache. Also it might be usefull to cache all partial view with media items via .CachedPartial or something like that.
Thanks
Hi Nicholas,
Thanks for the tips. Apologies for my lack of experience in this area but how did you go about creating an in-memory cache of the media?
Basically, whenever I fetch media, I store it in a dictionary so I don't have to fetch it again next time. In the above example, I created something I called an InstanceByKeyCache (basically, a dictionary): https://github.com/rhythmagency/rhythm.umbraco.extensions/blob/develop/trunk/Rhythm.Extensions/Rhythm.Extensions/Types/InstanceByKeyCache.cs
I also built a MediaCacheInvalidator to update my InstanceByKeyCache whenever the media changed: https://github.com/rhythmagency/rhythm.umbraco.extensions/blob/develop/trunk/Rhythm.Extensions/Rhythm.Extensions/Types/MediaCacheInvalidator.cs
My caches didn't store relationships though, so you might want to create a somewhat different cache if you'd like to store parent/child media relationships.
On a different note, but related to media, I have the following code that creates some folders when a member type of School is created. It adds a school folder under the vacancies area and then adds a Live, Pending and Closed folder under that school.
Can you seen any reason why the creation of the four folders would take so long to complete??
How long is "so long"?
is working on a reply...