From 6403e3e3d10df28b521cea955a891c6c7de36944 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 23 Nov 2012 12:48:41 +0100 Subject: [PATCH] spotify: Reuse artist, album, and track models This adds a module-level cache of artist, album, and track models, whose content is almost entirely static. This cache is used when we convert from pyspotify to Mopidy objects. Previously, an album with 15 tracks would create 15 track objects, 15 artists objects on the tracks, 15 album objects on the tracks, and 15 artist objects on the 15 album objects, in total 60 objects. With this change, we only create 15 track objects, 1 album object, and 1 artist object, in total 17 objects. Measurements with 90 playlists containing about 6500 tracks in total shows that this reduces the number of Artist objects from 13600 to 3800, and the number of Album objects from 6500 to 4500 objects. An unscientific measurement of memory usage using ps(1) indicated a reduction in RSS from 71MB to 65MB, measured right after the Spotify playlists was loaded the first time. --- mopidy/backends/spotify/translator.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/mopidy/backends/spotify/translator.py b/mopidy/backends/spotify/translator.py index 92b4514e..4d2f36a0 100644 --- a/mopidy/backends/spotify/translator.py +++ b/mopidy/backends/spotify/translator.py @@ -6,32 +6,45 @@ from mopidy import settings from mopidy.models import Artist, Album, Track, Playlist +artist_cache = {} +album_cache = {} +track_cache = {} + + def to_mopidy_artist(spotify_artist): if spotify_artist is None: return uri = str(Link.from_artist(spotify_artist)) + if uri in artist_cache: + return artist_cache[uri] if not spotify_artist.is_loaded(): return Artist(uri=uri, name='[loading...]') - return Artist(uri=uri, name=spotify_artist.name()) + artist_cache[uri] = Artist(uri=uri, name=spotify_artist.name()) + return artist_cache[uri] def to_mopidy_album(spotify_album): if spotify_album is None: return uri = str(Link.from_album(spotify_album)) + if uri in album_cache: + return album_cache[uri] if not spotify_album.is_loaded(): return Album(uri=uri, name='[loading...]') - return Album( + album_cache[uri] = Album( uri=uri, name=spotify_album.name(), artists=[to_mopidy_artist(spotify_album.artist())], date=spotify_album.year()) + return album_cache[uri] def to_mopidy_track(spotify_track): if spotify_track is None: return uri = str(Link.from_track(spotify_track, 0)) + if uri in track_cache: + return track_cache[uri] if not spotify_track.is_loaded(): return Track(uri=uri, name='[loading...]') spotify_album = spotify_track.album() @@ -39,7 +52,7 @@ def to_mopidy_track(spotify_track): date = spotify_album.year() else: date = None - return Track( + track_cache[uri] = Track( uri=uri, name=spotify_track.name(), artists=[to_mopidy_artist(a) for a in spotify_track.artists()], @@ -48,6 +61,7 @@ def to_mopidy_track(spotify_track): date=date, length=spotify_track.duration(), bitrate=settings.SPOTIFY_BITRATE) + return track_cache[uri] def to_mopidy_playlist(spotify_playlist):