2009-06-16, 14:51
While working on the hdflagging branch, there was a brief period of time where the performance hit associated with loading the extra stream information was discussed. Some generous xbmc users sent me their large databases (~1,000 movies) for performance testing.
What I found is that in loading the CFileItem list in CVideoDatabase::GetMoviesByWhere in ~5000ms, time was spent roughly in this proportion:So the actual reading from the database only takes 20% of the load time, but the innocent looking CFileItem(VideoInfoTag &) was taking 70%. The dataset::next was a hotspot addressed by the sqlite scrolling patch and is now down to 4%, which still may be a little high but this thread is about CFileItem()!
What in the ctor is taking so much time? 90+% of it is spent in FillInDefaultIcon(). In fact, a call to FillInDefaultIcon:
2ms: smb://user:pass@server/path/to/file/name.avi
7.5ms: stack://smb://user:pass@server/path/to/file/name-cd1.avi, smb://user:pass@server/path/to/file/name-cd2.avi
For comparison, at 60Hz you only get 16.6ms to render a frame so 7.5ms is a huge number. The problem boils down to things like IsAudio() and IsVideo() etc taking too long, and these functions aren't just called here; they're even called from frame updates.
So a quick fix would be to have CFileItem(VideoInfoTag &) set it's default icon directly, since we know we've got a video or else there wouldn't be a VideoInfoTag. That reduces the load time on this test database from ~5s to ~2s. Delaying SetCachedVideoThumb() until it is needed reduces it further to 1.2s but that's beyond the scope of what I wanted to discuss.
Another quick performance increase would be to rearrange the if/else structure of FillInDefaultIcon() so that the statements are in descending result set size. Playlists are probably the smallest number of items anyone has but is always checked first over more common file types like audio and video. Should at least move IsPlaylist and IsXBE down below common media types.
Ok this is getting long but to sum up:
-- CFileItem(VideoInfoTag &) takes forever
-- Can we directly set the default icon instead of using FillInDefaultIcon()?
-- IsVideo, IsAudio et al take much longer than they should
What I found is that in loading the CFileItem list in CVideoDatabase::GetMoviesByWhere in ~5000ms, time was spent roughly in this proportion:
Code:
20% CVideoInfoTag movie = GetDetailsForMovie(m_pDS);
...
71% CFileItemPtr pItem(new CFileItem(movie));
...
08% m_pDS->next();
What in the ctor is taking so much time? 90+% of it is spent in FillInDefaultIcon(). In fact, a call to FillInDefaultIcon:
2ms: smb://user:pass@server/path/to/file/name.avi
7.5ms: stack://smb://user:pass@server/path/to/file/name-cd1.avi, smb://user:pass@server/path/to/file/name-cd2.avi
For comparison, at 60Hz you only get 16.6ms to render a frame so 7.5ms is a huge number. The problem boils down to things like IsAudio() and IsVideo() etc taking too long, and these functions aren't just called here; they're even called from frame updates.
So a quick fix would be to have CFileItem(VideoInfoTag &) set it's default icon directly, since we know we've got a video or else there wouldn't be a VideoInfoTag. That reduces the load time on this test database from ~5s to ~2s. Delaying SetCachedVideoThumb() until it is needed reduces it further to 1.2s but that's beyond the scope of what I wanted to discuss.
Another quick performance increase would be to rearrange the if/else structure of FillInDefaultIcon() so that the statements are in descending result set size. Playlists are probably the smallest number of items anyone has but is always checked first over more common file types like audio and video. Should at least move IsPlaylist and IsXBE down below common media types.
Ok this is getting long but to sum up:
-- CFileItem(VideoInfoTag &) takes forever
-- Can we directly set the default icon instead of using FillInDefaultIcon()?
-- IsVideo, IsAudio et al take much longer than they should