raspberry pi large list performance
#1
I run xbmc on raspberry pi. One annoyance I've had is that large lists seem to load very slowly. I write web and mobile applications (mostly in python / java) but don't have a lot of experience with C++ / desktop apps.

One of the things we sometimes do in the web and mobile world when we need fast performance in large ListViews is to not actually load the list, but rather only what needs to be visible to the user, and then basically lie about the scrollbar height. The general theory behind this approach is that loading 10000 strings into an array and iterating through it is relatively inexpensive, while loading 10000 rows into the UI at one time is relatively more expensive.

Here's an example of an implementation of such an approach using javascript and html:
http://mleibman.github.io/SlickGrid/exam...imple.html
Grab the scroll bar and yank it around a bunch - you'll notice that the list blinks a little between redraws.
https://github.com/mleibman/SlickGrid

I understand that the iOS listview for iPhone uses this same principal.

Anyways, I was thinking of forking it on github and taking a shot at implementing the above approach, but I thought I'd try and get some feedback first, since I haven't spent a lot of time working with this sort of architecture. Is this something xbmc might benefit from?
Reply
#2
Optimising the listviews for low powered devices would be a great idea, it's certainly true that there is a noticeable (although not unusable) delay of several (~7) seconds on a Pi (@1GHz) when entering the Movie view, and that's with just 400 movies (not including Sets). Since I'm only seeing 10 movies at a time, dynamically loading new items as the user scrolls through the list would seem like a better approach than loading everything at once (which I'm assuming is what is happening).

Accessing Songs, with 7400 items in my MySQL-hosted library, is not really practical on a Pi as it takes 25 seconds to display the Song list.

Once problem I can foresee is that jumping around the list using letters (T9-type number pad) could be impacted by loading the list dynamically.
Texture Cache Maintenance Utility: Preload your texture cache for optimal UI performance. Remotely manage media libraries. Purge unused artwork to free up space. Find missing media. Configurable QA check to highlight metadata issues. Aid in diagnosis of library and cache related problems.
Reply
#3
(2013-05-07, 22:32)fuhrysteve Wrote: One of the things we sometimes do in the web and mobile world when we need fast performance in large ListViews is to not actually load the list, but rather only what needs to be visible to the user, and then basically lie about the scrollbar height. The general theory behind this approach is that loading 10000 strings into an array and iterating through it is relatively inexpensive, while loading 10000 rows into the UI at one time is relatively more expensive.

IIRC we already do this, but I might be wrong.

Afaik the biggest problem is that when you scroll we need to prepare textures for the new items and this can block the animations. Which I think the deffered render model will help solve quite a bit
If you have problems please read this before posting

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.

Image

"Well Im gonna download the code and look at it a bit but I'm certainly not a really good C/C++ programer but I'd help as much as I can, I mostly write in C#."
Reply
#4
(2013-05-08, 08:28)topfs2 Wrote: IIRC we already do this, but I might be wrong.

Upon entering the Movies view, it's executing
Code:
07:41:53 T:3042930688   DEBUG: RunQuery took 507 ms for 598 items query: select * from movieview

so it appears to be loading all movies (I have 400 movies, 198 of which are in sets) although this is happening fairly quickly.

What's quite interesting is that, once in the Movies view, if you enter a Set and then return back to the Movies view, it's still slow to display the Movies list (as long, if not longer, than when first entered), and there appears to be no database access taking place, it's all from memory - so some process is crunching on this stored data and appears to be accounting for the delay, not the actual database load.
Texture Cache Maintenance Utility: Preload your texture cache for optimal UI performance. Remotely manage media libraries. Purge unused artwork to free up space. Find missing media. Configurable QA check to highlight metadata issues. Aid in diagnosis of library and cache related problems.
Reply
#5
To speed things up for slower devices is a great idea.
Reply
#6
Looking at MySQL logs, it certainly appears as though the database is only accessed the very first time the Movies view is entered (select * from moviesview), and never again on subsequent entry to the Movies view (either from the Main Menu or when exiting out of a child Set folder).

Since the data load appears to be very quick, it can't be blamed for causing the delays, even though it appears to be loading all of the items - in fact, the first entry to the Movies view is often the fastest, with subsequent entries (those without the database access) often noticeably slower. An example - first entry (with database load): 6 seconds, subsequent entry (without db load): 10 seconds.

Code:
130508  8:04:01 198963 Connect  [email protected] on
                198963 Query    SET NAMES utf8
                198963 Query    show databases like 'pivideo75'
                198963 Query    show tables
                198963 Init DB  pivideo75
                198963 Query    show databases like 'pivideo75'
                198963 Query    show tables
130508  8:04:11 198963 Query    select idPath from path where strPath='videodb://1/2/'
                198963 Query    select path.strContent,path.strScraper,path.scanRecursive,path.useFolderNames,path.strSettings,path.noUpdate, path.exclude from path where strPath='videodb://1/'
                198963 Query    select path.strContent,path.strScraper,path.scanRecursive,path.useFolderNames,path.strSettings,path.noUpdate, path.exclude from path where strPath='videodb://'
                198964 Connect  [email protected] on

It would be interesting to know what the Pi is doing between 8:04:01 and 8:04:11, as this is the bulk of the delay when entering Movies view. From the debug log, it appears to be "Loading fileitems" (is this accessing the filesystem - it's NFS - I certainly hope not!)

Code:
08:04:01 T:3043319808   DEBUG: ------ Window Init (MyVideoNav.xml) ------
08:04:01 T:3043319808   DEBUG: CGUIMediaWindow::GetDirectory (videodb://1/2/)
08:04:01 T:3043319808   DEBUG:   ParentPath = [videodb://1/2/]
08:04:01 T:3043319808   DEBUG: Loading fileitems [videodb://1/2/]
08:04:11 T:3043319808   DEBUG:   -- items: 598, directory: videodb://1/2/ sort method: 0, ascending: false
08:04:11 T:2831152224  NOTICE: Thread Background Loader start, auto delete: false
08:04:12 T:2831152224   DEBUG: Thread Background Loader 2831152224 terminating
08:04:13 T:2831152224  NOTICE: Thread Background Loader start, auto delete: false

Edit: According to nfsstat, "Loading fileitems" doesn't appear to be hitting the filesystem... though I could be wrong about that. It's certainly where the delays are occurring.
Texture Cache Maintenance Utility: Preload your texture cache for optimal UI performance. Remotely manage media libraries. Purge unused artwork to free up space. Find missing media. Configurable QA check to highlight metadata issues. Aid in diagnosis of library and cache related problems.
Reply
#7
Looking at FileItem.cpp it appears to be loading/transforming a disc cache using the CArchive class - it seems to be this process that is slow on a Pi, it's entirely memory/CPU bound so perhaps not surprising.

Other than transforming only the data that needs to be displayed (ie. 10 items at a time), the only other obvious optimisation would be to speed up CArchive.
Texture Cache Maintenance Utility: Preload your texture cache for optimal UI performance. Remotely manage media libraries. Purge unused artwork to free up space. Find missing media. Configurable QA check to highlight metadata issues. Aid in diagnosis of library and cache related problems.
Reply
#8
(2013-05-08, 08:48)MilhouseVH Wrote: Upon entering the Movies view, it's executing
Code:
07:41:53 T:3042930688   DEBUG: RunQuery took 507 ms for 598 items query: select * from movieview

so it appears to be loading all movies (I have 400 movies, 198 of which are in sets) although this is happening fairly quickly.

Notice what I replied to.. I stated that I believed we only rendered what we needed, not that we didn't fetch more. That we fetch more than needed is something we are painfully aware of (one of the biggest problems with plugins is this).

(2013-05-08, 09:22)MilhouseVH Wrote: Looking at FileItem.cpp it appears to be loading/transforming a disc cache using the CArchive class - it seems to be this process that is slow on a Pi, it's entirely memory/CPU bound so perhaps not surprising.

Other than transforming only the data that needs to be displayed (ie. 10 items at a time), the only other obvious optimisation would be to speed up CArchive.

I guess the slow harddrive is to blame for that. Altering CArchive to use RAM as much as possible might help
If you have problems please read this before posting

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.

Image

"Well Im gonna download the code and look at it a bit but I'm certainly not a really good C/C++ programer but I'd help as much as I can, I mostly write in C#."
Reply
#9
(2013-05-08, 09:32)topfs2 Wrote: Notice what I replied to.. I stated that I believed we only rendered what we needed, not that we didn't fetch more. That we fetch more than needed is something we are painfully aware of (one of the biggest problems with plugins is this).

Yes, it's most likely this that is the problem - loading more data than is required, as it then means there is more data to transform, which is where the delay is occurring.

(2013-05-08, 09:32)topfs2 Wrote: I guess the slow harddrive is to blame for that. Altering CArchive to use RAM as much as possible might help

C++ isn't really part of my skill set, but is this actually reading/writing to HDD (which in my case, is across the network as I've got the .xbmc folder mounted over NFS). Moving CArchive to use RAM would seem like a potential optimisation candidate, provided the amount of RAM required isn't too significant (but would need to be bounded). Transforming data on demand might be the ideal solution though - lower RAM overhead, faster load time, but no doubt a lot more refactoring required.
Texture Cache Maintenance Utility: Preload your texture cache for optimal UI performance. Remotely manage media libraries. Purge unused artwork to free up space. Find missing media. Configurable QA check to highlight metadata issues. Aid in diagnosis of library and cache related problems.
Reply
#10
(2013-05-08, 09:34)MilhouseVH Wrote: Yes, it's most likely this that is the problem - loading more data than is required, as it then means there is more data to transform, which is where the delay is occurring.

Not necessarily. Depends on if the delay is when you scroll or when you enter the window. If its the former its not due to loading to much, as having it in memory (which we have after used CArchive) is the best course of action. If its the latter then keeping CArchive in memory is a good choice.

TBH I'm not 100% on how we handle CArchive and if its lazily kept in memory or not. IIRC it stores it on disk always.

(2013-05-08, 09:34)MilhouseVH Wrote: C++ isn't really part of my skill set, but is this actually reading/writing to HDD (which in my case, is across the network as I've got the .xbmc folder mounted over NFS). Moving CArchive to use RAM would seem like a potential optimisation candidate, provided the amount of RAM required isn't too significant (but would need to be bounded). Transforming data on demand might be the ideal solution though - lower RAM overhead, faster load time, but no doubt a lot more refactoring required.

xbmc doesn't really have a unified memory manager, which is why we don't lazily keep stuff in memory. Each subsystem tries to use minimal amount of RAM (xbox legacy essentially) and some subsystems try to keep it a little. There is no unified and global manager which states what needs to be unloaded and what may be kept.

So yeah, a bit of refactoring is needed Smile
If you have problems please read this before posting

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.

Image

"Well Im gonna download the code and look at it a bit but I'm certainly not a really good C/C++ programer but I'd help as much as I can, I mostly write in C#."
Reply
#11
(2013-05-08, 10:38)topfs2 Wrote: Not necessarily. Depends on if the delay is when you scroll or when you enter the window. If its the former its not due to loading to much, as having it in memory (which we have after used CArchive) is the best course of action. If its the latter then keeping CArchive in memory is a good choice.

TBH I'm not 100% on how we handle CArchive and if its lazily kept in memory or not. IIRC it stores it on disk always.

The delay occurs before the list is displayed (so, before the window is entered). Once in the window, there is no significant or noteworthy delay. My guess is that CArchive is created each time the window is entered, and there is no caching of the CArchive data. What would be nice is to transform the data as it is required (as it is displayed), rather than transforming all of it up front even though only 10 items may ever be shown.
Texture Cache Maintenance Utility: Preload your texture cache for optimal UI performance. Remotely manage media libraries. Purge unused artwork to free up space. Find missing media. Configurable QA check to highlight metadata issues. Aid in diagnosis of library and cache related problems.
Reply
#12
Ah, rereading OP I see that both of you stated it was initial slowdown. Yeah that can very well be due to CArchive or the fact that we fetch all directory/library content before display.
If you have problems please read this before posting

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.

Image

"Well Im gonna download the code and look at it a bit but I'm certainly not a really good C/C++ programer but I'd help as much as I can, I mostly write in C#."
Reply
#13
popcornmix and a colleague at the Raspberry Pi Foundation have been working on patches to improve library list performance (see here). I've tested these patches on a 1GHz 512MB Pi running OpenELEC 3.1.x with /storage mounted over NFS, and performance has improved.

However, the biggest difference for me (though popcornmix is unable to confirm this) comes from disabling the filecache which is literally a waste of time on my system. I'm not sure why the filecache exists, presumably it's to avoid slow database queries on older (XBOX era?) hardware, but I currently see much better performance without it.

For example, to display the Movies library (632 items) with filecache enabled: ~13 seconds, and with the filecache disabled: ~5 seconds.

As already said, popcormix is unable to reproduce my filecache observations, so perhaps it has something to do with running /storage over NFS which means the file cache is being written and read across the network. However, popcornmix saw no marked difference between having the filecache enabled or disabled, which begs the question is the filecache still necessary? In some cases - ie. mine, possibly due to NFS - it has a very big negative impact on performance.
Texture Cache Maintenance Utility: Preload your texture cache for optimal UI performance. Remotely manage media libraries. Purge unused artwork to free up space. Find missing media. Configurable QA check to highlight metadata issues. Aid in diagnosis of library and cache related problems.
Reply
#14
My colleague spent a long time even getting the cache code to be invoked. This is when he finally found the difference in mine and his results:

Quote:It's all about the exact way you navigate the XBMC user interface:

1) Click on Videos itself (not one of the buttons under), choose Movies then Title -> no cache is ever used
2) Click on Library button under Videos, choose Movies then Title -> no cache is ever used
3) Click on Movies itself (not one of the buttons under) -> attempts to use cache
4) Click on Title button under Movies -> attempts to use cache

In all 4 cases, what you get is the same list of film titles, under the
somewhat illogical heading "Videos - Title", since there's no way to get
there via something marked "Videos" and immediately thereafter "Title".

Some logging I wrote last week sprung into life, and tells me that the
slow part of CFileItemList::Load (from where the troublesome "Loading
fileitems" debug is generated) is the line
...

Does anyone know if this is a plain bug, or intended for some reason?
The fact that people haven't reported the cache bypassing route as being particularly slow is more evidence that the cache is not providing a big win.
Reply
#15
@popcornmix: is your quote truncated - it seems to have missed off the really good bit! Smile

I had noticed the somewhat arbitrary cache usage behaviour, which is why my timings relate only to entering Movies via the main menu item, as I know this is when the cache will be used.

In fact, as mentioned in the patch comments, I experience different timings for the initial entry to Movies (when the cache is created and saved) and a much longer delay on subsequent entries to Movies when the cache is retrieved and loaded. Disabling the cache entirely (so that it isn't saved, and thus can't be loaded) means I experience consistently better performance each time I enter Movies. Are you now seeing this first/second entry timing difference too, or is it still a peculiarity of my setup?

Strangely, the improvement I see as a result of disabling the cache entirely isn't reflected in Music -> Artists and Music -> Songs where the cache is also used (but not Music -> Albums, where bizarrely no cache is ever used). In the case of Music -> Artists/Songs, there is no performance difference with or without the cache, which would tend to rule out /storage over NFS as the cause of the delay for Movies.

Best case, the cache is of no benefit. Worst case, it's a very significant overhead.
Texture Cache Maintenance Utility: Preload your texture cache for optimal UI performance. Remotely manage media libraries. Purge unused artwork to free up space. Find missing media. Configurable QA check to highlight metadata issues. Aid in diagnosis of library and cache related problems.
Reply

Logout Mark Read Team Forum Stats Members Help
raspberry pi large list performance0