Skip to content

Conversation

@payno
Copy link
Member

@payno payno commented Sep 8, 2025

  • silx.gui.plot: ColormapMixIn: replace usage of a dict for the '__cacheColormapRange' by a LRU cache.

@payno payno force-pushed the colormap_upgrade_cache branch 4 times, most recently from 010b974 to 1b78b29 Compare September 8, 2025 12:56
class ColormapMixIn(_Colormappable, ItemMixInBase):
"""Mix-in class for items with colormap"""

COLORMAP_CACHE_SIZE = 25
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The size is pretty arbitrary. Maybe it can be worth to increase it a bit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me as it is, but you can increase it a bit if you want:
If you propose a slider with integer steps for the percentile, having COLORMAP_CACHE_SIZE = 128 would store all possible values.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes good point, lets go for 128.

None if data is None else numpy.array(data, copy=copy or NP_OPTIONAL_COPY)
)
self.__cacheColormapRange = {} # Reset cache
self.__cacheColormapRange.clear()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using clear is clearer... without bad wordplay.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clearer indeed!

@payno payno force-pushed the colormap_upgrade_cache branch from 1b78b29 to e00da8a Compare September 8, 2025 13:16
@payno payno force-pushed the colormap_upgrade_cache branch from e00da8a to 870dcdd Compare September 8, 2025 13:54
@payno payno force-pushed the colormap_upgrade_cache branch from 5101584 to f9d95ba Compare September 10, 2025 05:04
from collections import OrderedDict


class LRUCache:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally I wanted to inherit directly from OrderedDict. See this commit.
But it turned out that this implementation fails with python 3.10. Because the getitem API is used when calling move_to_end. So the appropriate way seems to have composition instead of inheritance. This forces me to expose the API...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not add the LRUCache class to the public API for a single usage inside the library.
Then, best to implement only the method that gets used.
Also, since it is used only in one class and get is called at a single place, you could call move_to_end directly from the code if vRange is not None here (with a comment):

vRange = self.__cacheColormapRange.get(key, None)
if vRange is None:
vRange = colormap._computeAutoscaleRange(data)
self.__cacheColormapRange[key] = vRange

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌 I moved the cache to silx.gui.plot.items._cache. After discussion we will keep the class for now as it also handle the limitation of the size and not only keeping the last element access at the end.

@payno payno changed the title DRAFT: Colormap upgrade cache Colormap upgrade cache Sep 10, 2025
@payno payno requested a review from t20100 September 10, 2025 09:36
Copy link
Member

@t20100 t20100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO much simpler not to have a complete LRUCache (and maybe not at all).
Anyway, best to not put LRUCache in the API

None if data is None else numpy.array(data, copy=copy or NP_OPTIONAL_COPY)
)
self.__cacheColormapRange = {} # Reset cache
self.__cacheColormapRange.clear()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clearer indeed!

from collections import OrderedDict


class LRUCache:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not add the LRUCache class to the public API for a single usage inside the library.
Then, best to implement only the method that gets used.
Also, since it is used only in one class and get is called at a single place, you could call move_to_end directly from the code if vRange is not None here (with a comment):

vRange = self.__cacheColormapRange.get(key, None)
if vRange is None:
vRange = colormap._computeAutoscaleRange(data)
self.__cacheColormapRange[key] = vRange

class ColormapMixIn(_Colormappable, ItemMixInBase):
"""Mix-in class for items with colormap"""

COLORMAP_CACHE_SIZE = 25
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me as it is, but you can increase it a bit if you want:
If you propose a slider with integer steps for the percentile, having COLORMAP_CACHE_SIZE = 128 would store all possible values.

@payno payno force-pushed the colormap_upgrade_cache branch from bcbcc24 to 03cb6da Compare September 12, 2025 13:31
@payno payno merged commit 61f7098 into main Sep 16, 2025
4 checks passed
@payno payno deleted the colormap_upgrade_cache branch September 16, 2025 14:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants