-
-
Notifications
You must be signed in to change notification settings - Fork 482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Caching and Memoization easy and powerful #1179
Comments
The initial plans for |
@philippjfr Thank you very much for your fast reply! Those plans sound great, I would love to see Panel support caching and memoization! Meanwhile, I tried to workaround by using cachier or joblib's Memory, and although both work correctly to reuse the cache between Jupyter Notebook runs (after restarting the kernel), they don't with Panel launched with a Bokeh server, as each cache gets a unique handler instead of reusing the same one (eg: Do you have any idea how I may work around this (forcing all caching requests to use the same cache without bokeh's unique id prepending) by any chance? |
Update: if anyone needs a workaround in the meantime, I have found that simple_cache and cache (but the latter does not have a licence) work well with pandas dataframes and Panel/Bokeh standalone server. I implemented my solution with simple_cache, and it works well to reuse the same cache across Boker server sessions/users (so different users will reuse the same cache, that's nice!). |
Yes! A pattern which automatically caches the source data frame caching would really help. For now was able to achieve this manually using class MyExplorer(param.Parameterized):
def __init__(self, **kwargs):
self.df = pn.state.cache["data"] if "data" in pn.state.cache else load_input()
pn.state.cache["data"] = self.df
@param.depends("...")
def make_view():
plot_df = transform(self.df)
return hv.Curve...
explorer = MyExplorer(name="")
dashboard = pn.Column(explorer.param, explorer.make_view) |
Oh thank you for the example, very helpful! I think your code snippet can be easily converted to a simple caching function decorator, which would be better than my current solution because then no other dependency would be needed :-) |
BackgroundI have now for a time been using DiskCache for memoization and caching. It is so easy and powerful to use. It persists your data to disk, i.e. speeds up your development process because your app/ server reloads so much faster. And the experience for users is so great. RequirementsMy requirements for an easier to use/ more powerful caching would be
SolutionI would suggest building it into Apipn.bind(my_func, input_value=input_widget, cache=True)
pn.bind(my_func, input_value=input_widget, cache=True, cache_options={"expire": 60}) # expires every 60s
pn.bind(my_func, input_value=input_widget, cache=True, cache_options={"caches": ["panel", "diskcache"]})
@pn.depends(input_value=input_widget, cache=True)
def my_func(input_value):
...
|
Thanks for that proposal @MarcSkovMadsen. I strongly agree with that and in fact when we first designed |
As of #2411 we now have a |
Panel is a wonderful piece of software, I love it, thanks a lot for making it!
However there is one thing that bugs me out, and it's the lack of caching and memoization. A simple, but I think very common case, is to cache the fetching of an external csv file. So far it seems that everytime a user reloads the page, the whole script is re-executed and the csv file must be redownloaded, which makes the loading quite slow (the user gets a blank page for about a minute, because I have multiple such csv files).
I know streamlit has support for this case, and also hvplot through datashader, but it's a quite complicated case and not as streamlined. Also, it doesn't allow as far as I understand to serve multiple different users with the same cache constructed by the first user, which would be ideal in terms of loading time.
Is there a caching and if possible memoization feature, maybe undocumented, in Panel? If not, is such a feature planned, or is there a known easy workaround (eg, by using another module)?
Thanks a lot in advance,
Best regards,
Stephen
The text was updated successfully, but these errors were encountered: