patterncsharpMinor
Property caching
Viewed 0 times
propertycachingstackoverflow
Problem
Trying to figure out how to efficiently cache property calculations with dependency tracking to invalidate the cache. Here is the syntax I have at the moment (one
Here
This one helps with flow API:
Dependency tracking done by:
```
public class Cached
{
public static implicit operator T(Cached cache) => cache.Value;
public Cached(Func factory, params Func[] dependencies)
{
if (factory == null)
throw new ArgumentNullException("factory");
if(dependencies == null || dependencies.Any(d => d == null))
throw new ArgumentNullException("dependancies");
_factory = factory;
_dependencies = dependencies;
}
public Cached Depending(params Func[] dependencies) =>
new Cached(_factory, _dependencies.Concat(dependenci
Cache instance supports multiple object properties):class Multiplication
{
public int Arg1 { get; set; }
public int Arg2 { get; set; }
public int Result => Cache
.Lazy(() => Arg1 * Arg2)
.From(() => Arg1, () => Arg2);
Cache Cache { get; } = new Cache();
}Here
Result is recalculated on Arg* change. Implementation classes:public class Cache
{
public LazyProperty Lazy(
Func factory,
[CallerMemberName] string memberName = "") =>
new LazyProperty(
value => (Cached)Store.GetOrAdd(memberName, value),
new Cached(factory));
ConcurrentDictionary Store { get; } =
new ConcurrentDictionary();
}This one helps with flow API:
public class LazyProperty
{
public static implicit operator T(LazyProperty property) => property.Resolve();
internal LazyProperty(Func, Cached> getOrAdd, Cached value)
{
GetOrAdd = getOrAdd;
Value = value;
}
public LazyProperty From(params Func[] dependencies) =>
new LazyProperty(GetOrAdd, Value.Depending(dependencies));
Func, Cached> GetOrAdd { get; }
Cached Value { get; }
Cached Resolve() => GetOrAdd(Value);
}Dependency tracking done by:
```
public class Cached
{
public static implicit operator T(Cached cache) => cache.Value;
public Cached(Func factory, params Func[] dependencies)
{
if (factory == null)
throw new ArgumentNullException("factory");
if(dependencies == null || dependencies.Any(d => d == null))
throw new ArgumentNullException("dependancies");
_factory = factory;
_dependencies = dependencies;
}
public Cached Depending(params Func[] dependencies) =>
new Cached(_factory, _dependencies.Concat(dependenci
Solution
You could potentially use incremental computation (think Excel cells that cache values).
Some details (in F#) here:
https://fsprojects.github.io/FSharp.Data.Adaptive/
The above is ported from the Incremental portion of the Aardvark project:
https://github.com/aardvark-platform/aardvark.base
The documentation is all F# since this model works well in a functional style, but it works similarly well in imperative (and is interoperable with C#)
https://rawgit.com/wiki/aardvark-platform/aardvark.docs/docs/base/adaptive-functional-programming.html
These do pretty much exactly what you want, with automatic dependency tracking and lazy value updating (on read).
There are some utility classes for interop with C# as well, and they work decently - but you still end up having to do some manual messy F# interop on occasion.
Unfortunately, the documentation is also a bit lacking, so reading code is often also necessary if you want to do more than the basics, but it's a quite powerful model.
Some details (in F#) here:
https://fsprojects.github.io/FSharp.Data.Adaptive/
The above is ported from the Incremental portion of the Aardvark project:
https://github.com/aardvark-platform/aardvark.base
The documentation is all F# since this model works well in a functional style, but it works similarly well in imperative (and is interoperable with C#)
https://rawgit.com/wiki/aardvark-platform/aardvark.docs/docs/base/adaptive-functional-programming.html
These do pretty much exactly what you want, with automatic dependency tracking and lazy value updating (on read).
There are some utility classes for interop with C# as well, and they work decently - but you still end up having to do some manual messy F# interop on occasion.
Unfortunately, the documentation is also a bit lacking, so reading code is often also necessary if you want to do more than the basics, but it's a quite powerful model.
Context
StackExchange Code Review Q#129081, answer score: 4
Revisions (0)
No revisions yet.