fossfreedom / coverart-browser

Browse your cover-art albums in Rhythmbox v2.96 - 3.0+
http://xpressubuntu.wordpress.com/
GNU General Public License v3.0
74 stars 19 forks source link

speed up loading in models #251

Open fossfreedom opened 10 years ago

fossfreedom commented 10 years ago

interesting conversation here on the py mailing list

"I'm developing an application using PyGObject and Python 3 for the Music Player Daemon (https://github.com/multani/sonata/) and I've got several users who are complaining about the lack of performance of the application when loading lot of song into our "Current" playlist (which is a Gtk.TreeView). Especially compared to other MPD clients which are nearly instantaneous.

I'm going to describe how the application currently works, the problem I'm facing and possible solutions I'm exploring. It's a bit long, so...

tl;dr: how to efficiently display (lot of) information into a TreeView?

Current implementation

Once we get the songs to be displayed, the application loops over all the songs and:

I made a small test case to reproduce the problem (attached to this email), and here are the results I've got:

[I got those values using:

In the real application, it's actually much longer due to the more complex formatting functions and inefficient access to the Song object attributes, but PyGObject always comes first with more thatn 60% of the time inside.

Possible solutions?

I tried several approaches to solve this problem:

I'm a bit out of idea on what else I can try. I can provide more information about those numbers, especially if you need some profiling data. I'm all in for more PyGObject performances too, although I don't where to start in the code base, but I'm willing to try stuff. "

https://drive.google.com/file/d/0B5yvyAZqOxQrQVVrWm42WUtzZVVaeWRzMjVLZXZKZU4xWkpZ/edit?usp=sharing

In Quod Libet we use an optimized single column ListStore subclass [0] with a few fast paths and hacks to remove the override overhead. We only use cell_data_func and do the formatting and detecting the current song in there. I think append_many() is about 3-4 times faster than Gtk.ListStore.append, so still not as fast as the old one (or reverse() + insert(0,x), which was even faster in pygtk), but more bearable.

Since I'm the sole copyright owner of that file I could multi-license it if needed.

Regarding scrolling: In addition to caching for formatting, I also save the last result for each cell_data_func and don't update the cell renderer if there is no new data. Depending on the type of formatting you do, you can skip the formatting or the set_property() call. The cell renderer happily draws the same thing in a different row then. Say, multiple redraws of the same cell, or it's an album name column where many entries are the same. This helped a bit in GTK+2 times at least.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/20440639-speed-up-loading-in-models?utm_campaign=plugin&utm_content=tracker%2F351726&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F351726&utm_medium=issues&utm_source=github).