-
-
Notifications
You must be signed in to change notification settings - Fork 486
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
Implement cache function for memoization support #2411
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
b64380a
Implement cache function for memoization support
philippjfr 444c32a
Drop LIFO
philippjfr 82574a4
Fix last commit
philippjfr 9673d16
Clean up implementation
philippjfr aa9443f
Clean up and fix flakes
philippjfr 0e999e9
Fix flakes
philippjfr df97a8c
Fix flakes
philippjfr 94be64c
Implement disk caching
philippjfr d6af9e5
Add docs
philippjfr 4d1d0ba
Add tests
philippjfr b5f3732
Add disk caching tests
philippjfr a190cef
Add diskcache dependency
philippjfr 47387fb
Improve tests
philippjfr 7a582bf
Print for CI debugging
philippjfr 22f0ee5
Use time.perf_counter on windows
philippjfr eef754d
Add small wait
philippjfr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,16 +14,13 @@ | |
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"When developing applications that are to be used by multiple users and which may process a lot of data it is important to ensure the application is well optimized. Additionally complex applications may have very complex callbacks which are difficult to trace and debug. In this user guide section we will walk you some of the best practices to debug your applications and profile your application to maximize performance." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"When developing applications that are to be used by multiple users and which may process a lot of data it is important to ensure the application is well optimized. Additionally complex applications may have very complex callbacks which are difficult to trace and debug. In this user guide section we will walk you some of the best practices to debug your applications and profile your application to maximize performance.\n", | ||
"\n", | ||
"## Caching\n", | ||
"\n", | ||
"The Panel architecture ensures that multiple user sessions can run in the same process and therefore have access to the same global state. This means that we can cache data in Panel's global `state` object, either by directly assigning to the `pn.state.cache` dictionary object or by using the `pn.state.as_cached` helper function.\n", | ||
"Caching data and computation is one of the most effective ways to speed up your applications. Some common examples of scenarios that benefit from caching is working with large datasets that you have to load from disk or over a network connection or you have to perform expensive computations that don't depend on any extraneous state. Panel makes it easy for you to add caching to you applications using a few approaches. Panel' architecture is also very well suited towards caching since multiple user sessions can run in the same process and therefore have access to the same global state. This means that we can cache data in Panel's global `state` object, either by directly assigning to the `pn.state.cache` dictionary object, using the `pn.state.as_cached` helper function or the `pn.cache` decorator. Once cached all current and subsequent sessions will be sped up by having access to the cache.\n", | ||
"\n", | ||
"### Manual usage\n", | ||
"\n", | ||
"To assign to the cache manually, simply put the data load or expensive calculation in an `if`/`else` block which checks whether the custom key is already present: \n", | ||
"\n", | ||
|
@@ -34,16 +31,42 @@ | |
" pn.state.cache['data'] = data = ... # Load some data or perform an expensive computation\n", | ||
"```\n", | ||
"\n", | ||
"### `pn.cache` decorator\n", | ||
"\n", | ||
"The `pn.cache` decorator provides an easy way to cache the outputs of a function depending on its inputs (i.e. `memoize`). If you've ever used the Python `@lru_cache` decorator you will be familiar with this concept. However the `pn.cache` functions supports additional cache `policy`'s apart from LRU (least-recently used), including `LFU` (least-frequently-used) and 'FIFO' (first-in-first-out). This means that if the specified number of `max_items` is reached Panel will automatically evict items from the cache based on this `policy`. Additionally items can be deleted from the cache based on a `ttl` (time-to-live) value given in seconds.\n", | ||
"\n", | ||
"#### Caching in memory\n", | ||
"\n", | ||
"The `pn.cache` decorator can easily be combined with the different Panel APIs including `pn.bind` and `pn.depends` providing a powerful way to speed up your applications.\n", | ||
"\n", | ||
"```python\n", | ||
"@pn.cache(max_items=10, policy='LRU')\n", | ||
"def load_data(path):\n", | ||
" return ... # Load some data\n", | ||
"```\n", | ||
"\n", | ||
"Once you have decorated your function with `pn.cache` any call to `load_data` will be cached in memory until `max_items` value is reached (i.e. you have loaded 10 different `path` values). At that point the `policy` will determine which item is evicted.\n", | ||
"\n", | ||
"#### Disk caching\n", | ||
"\n", | ||
"If you have `diskcache` installed you can also cache the results to disk by setting `to_disk=True`. The `diskcache` library will then cache the value to the supplied `cache_path` (defaulting to `./cache`). Making use of disk caching allows you to cache items even if the server is restarted.\n", | ||
"\n", | ||
"#### Clearing the cache\n", | ||
"\n", | ||
"Once a function has been decorated with `pn.cache` you can easily clear the cache by calling `.clear()` on that function, e.g. in the example above you could call `load_data.clear()`. If you want to clear all caches you may also call `pn.state.clear_caches()`.\n", | ||
"\n", | ||
"### `pn.state.as_cached`\n", | ||
"\n", | ||
"The `as_cached` helper function on the other hand allows providing a custom key and a function and automatically caching the return value. If provided the `args` and `kwargs` will also be hashed making it easy to cache (or memoize) on the arguments to the function: \n", | ||
"\n", | ||
"```python\n", | ||
"def load_data(*args, **kwargs):\n", | ||
" return ... # Load some data\n", | ||
" return ... # Load some data\n", | ||
"\n", | ||
"data = pn.state.as_cached('data', load_data, *args, **kwargs)\n", | ||
"```\n", | ||
"\n", | ||
"The first time the app is loaded the data will be cached and subsequent sessions will simply look up the data in the cache, speeding up the process of rendering. If you want to warm up the cache before the first user visits the application you can also provide the `--warm` argument to the `panel serve` command, which will ensure the application is initialized as soon as it is launched. If you want to populate the cache in a separate script from your main application you may also provide the path to a setup script using the `--setup` argument to `panel serve`. If you want to periodically update the cache look into the ability to [schedule tasks](Deploy_and_Export.ipynb#Scheduling-task-with-pn.state.schedule_task)." | ||
"The first time the app is loaded the data will be cached and subsequent sessions will simply look up the data in the cache, speeding up the process of rendering. If you want to warm up the cache before the first user visits the application you can also provide the `--warm` argument to the `panel serve` command, which will ensure the application is initialized as soon as it is launched. If you want to populate the cache in a separate script from your main application you may also provide the path to a setup script using the `--setup` argument to `panel serve`. If you want to periodically update the cache look into the ability to [schedule tasks](Deploy_and_Export.ipynb#Scheduling-task-with-pn.state.schedule_task).\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To me this looks like extensive and great documentation. |
||
] | ||
}, | ||
{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love the support for diskcache