Skip to content
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

Add memoization to dynamic Callable class #1063

Merged
merged 4 commits into from Jan 16, 2017
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.
+5 −5
Diff settings

Always

Just for now

Prev

Cleaned up dynamic Callable

  • Loading branch information...
Philipp Rudiger Philipp Rudiger
Philipp Rudiger authored and Philipp Rudiger committed Jan 16, 2017
commit 8a701c83a83256b82127a52db9b756a8bc33c2ad
Copy path View file
@@ -406,8 +406,8 @@ class Callable(param.Parameterized):
makes it possible to traverse the graph of operations applied
to a DynamicMap. Additionally a Callable will memoize the last
returned value based on the arguments to the function and the
state of all streams on its inputs, avoiding calling the function
unncessarily.
state of all streams on its inputs, to avoid calling the function
unnecessarily.
"""

This comment has been minimized.

Copy link
@jlstevens

jlstevens Jan 16, 2017

Contributor

Typo.


callable_function = param.Callable(default=lambda x: x, doc="""
@@ -421,8 +421,8 @@ def __init__(self, **params):
self._memoized = {}

def __call__(self, *args, **kwargs):
inputs = [inp for inp in self.inputs if isinstance(inp, DynamicMap)]
streams = [s for inp in inputs for s in get_nested_streams(inp)]
inputs = [i for i in self.inputs if isinstance(i, DynamicMap)]
streams = [s for i in inputs for s in get_nested_streams(i)]
values = tuple(tuple(sorted(s.contents.items())) for s in streams)

This comment has been minimized.

Copy link
@jlstevens

jlstevens Jan 16, 2017

Contributor

This means it is memoizing on the stream parameters in ascending alphanumeric order. I think that is fine (and makes sense!) but it is worth noting that this is one particular policy for how streams parameters are ordered into a tuple key. This is important to stay consistent if we ever need it somewhere else and I am now wondering if it might be worth having a utility to codify the idea....up to you.

This comment has been minimized.

Copy link
@philippjfr

philippjfr Jan 16, 2017

Author Contributor

It really doesn't matter much, it just needs to be consistently ordered. If we're using it somewhere else it can use the same scheme or another scheme without having any effect here.

This comment has been minimized.

Copy link
@jlstevens

jlstevens Jan 16, 2017

Contributor

True - my point is that we should try to be consistent anyway!

key = args + tuple(sorted(kwargs.items())) + values

@@ -517,7 +517,7 @@ class DynamicMap(HoloMap):
""")

def __init__(self, callback, initial_items=None, **params):
if not isinstance(callback, Callable) and not isinstance(callback, types.GeneratorType):
if not isinstance(callback, (Callable, types.GeneratorType)):
callback = Callable(callable_function=callback)

This comment has been minimized.

Copy link
@jlstevens

jlstevens Jan 16, 2017

Contributor

This means all callbacks will now be wrapped in Callable. This is a change from the previous behavior, and probably a good one (more consistent, at least with __mull__) though we should now document this. It would also be good to have an example of where a user might want to supply Callable themselves....

This comment has been minimized.

Copy link
@jlstevens

jlstevens Jan 16, 2017

Contributor

For instance, we might want an example of the user declaring a Callable with their own set of inputs.

super(DynamicMap, self).__init__(initial_items, callback=callback, **params)

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.