kciesielski / macmemo Goto Github PK
View Code? Open in Web Editor NEWScala macro-based utility for function memoization
License: Apache License 2.0
Scala macro-based utility for function memoization
License: Apache License 2.0
Current implementation of 'memoization macro toggle' works at compile time, which results in need of re-building particular classes whenever we want to turn memoization on / off.
We could perform appropriate property checking at runtime.
I tried to use this for an implicit def
that takes type parameters and implicit parameters, but the caching never kicked in
@xeno-by brought us an idea how we could perform memo builder resolution in more elegant way (548c7ca#commitcomment-7918497).
I'm going to apply his suggestion.
I've almost done feature that brings possibility for choosing custom cache providers, preserving the Guava as a default one.
You can check the code in my WIP branch here: https://github.com/mkubala/macmemo/tree/wip-cache-provider
(The test cases in my WIP-branch will be rewriten, so keep calm, I'm aware about it's ugliness ;) And I'll introduce some docs & examples later, when I'll get a rid of some doubts, described below).
Few weeks ago we were talking about leveraging implicits to achieve the goal.
It seems that it's impossible to use one class with many cache providers without manipulating cached method's signatures by adding implicit args to them.
I would avoid such kind of 'magic in background' because it can make code behaviour unpredictable..
And because implicits will be resolved at cacheable entity's compile time, we have to bring CacheProvider into type definition scope, instead of an 'usage scope' (I have no idea how to name it, so don't hesitate yourself to ask if my explanation isn't clear).
Therefore I'm not sure if providing default CacheProvider is a good idea.
This may suppress errors indicating that macmemo users actually do something wrong - for example have not brought Provider into class definition scope, but into class usage scope instead.. They may not gen up on using Guava provider in place where they're expecting the Memcached to be used..
We should, at least, emit some warning whenever a default provider is choosen.
What do you think about that?
Or maybe altering metod's signature will be the lesser evil in your opinion?
An example seems to be whenever breakout is used:
val myInts = Seq(1, 2, 3, 4, 5)
@memoize(maxSize = 10, expiresAfter = 12 hours)
def getAsList(intsIn: Iterable[Int]): List[Int] = intsIn.map { c => c }(breakOut)
getAsList(myInts).foreach(ii => println(ii))
Results in:
Error:(16, 6) type mismatch;
found : scala.collection.immutable.IndexedSeq[Int]
required: List[Int]
@memoize(maxSize = 10, expiresAfter = 12 hours)
The following code not works:
import com.softwaremill.macmemo.memoize
class GraphBuilder {
val max = 20000
// val max = read from props file.
@memoize(maxSize = max, expiresAfter = 2 hours)
def creatGraph(elementCount: Int): Graph = {
someExpensiveCode()
}
}
what about making the parameters are call by name? just like this:
class memoize(maxSize: => Long, expiresAfter: => FiniteDuration, concurrencyLevel: => Option[Int] = None)
Hello,
I'm really looking forward to trying macmemo. Our project uses maven.
I'm getting the following error when attempting to build:
[ERROR] Failed to execute goal on project dairy-econ: Could not resolve dependencies for project edu.cornell.ansci:dairy-econ:pom:0.0.1-SNAPSHOT: Failed to collect dependencies for [org.scala-lang:scala-compiler:jar:2.11.8 (compile), org.scala-lang:scala-library:jar:2.11.8 (compile), pl.metastack:metarx_2.11:jar:0.1.6 (compile), com.chuusai:shapeless_2.11:jar:2.3.2 (compile), com.softwaremill.macmemo:macros_2.11:jar:0.3 (compile), com.google.code.findbugs:jsr305:jar:1.3.0 (compile)]: No versions available for com.google.code.findbugs:jsr305:jar:[1.3,1.4) within specified range -> [Help 1]
I can't seem to find the right version (1.3 or 1.4) on maven central; I tried 1.3.9, as well as the latest (3.0.1) to no avail:
http://search.maven.org#search|gav|1|g%3A"com.google.code.findbugs"%20AND%20a%3A"jsr305"
I've tried with and without including the jsr305 dependency directly, and have tried deleting (rm -fr ./repository/com/google/code/findbugs
) the jsr305 directory and rerunning.
Here are some relevant excerpts from my pom file:
...
<scala.version.major>2.11</scala.version.major>
<scala.version.minor>8</scala.version.minor>
<scala.version>
${scala.version.major}.${scala.version.minor}
</scala.version>
...
<dependency>
<groupId>com.chuusai</groupId>
<artifactId>shapeless_${scala.version.major}</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.softwaremill.macmemo</groupId>
<artifactId>macros_${scala.version.major}</artifactId>
<version>0.3</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.9</version>
</dependency>
...
<configuration>
<compilerPlugins>
<compilerPlugin>
<groupId>org.scalamacros</groupId>
<artifactId>paradise_${scala.version}</artifactId>
<version>2.1.0</version>
</compilerPlugin>
</compilerPlugins>
</configuration>
...
User story: I have a program that undergoes periods of simulation, then reporting on the simulation. During the simulation, I would like to mark some or maybe all @memoized functions as being "volatile", that is to say, not memoized. During reporting, the values returned from functions are not expected to change, so at that point they should be memoized.
A means to invalidate the cache (for some or all @memoized functions) could also be useful in some cases, but immediately going back to being cached would prove to be a problem for the above use case.
Another dimension of this is that sometimes, only values resulting from a specific argument pattern may need to be invalidated; if we invalidated everything from the function, this could greatly reduce performance in some cases. For instance, in the above user story, we may have multiple unique "simulation ids", and just because we run a new simulation, doesn't mean we need to recalculate all the data generated for the old simulation.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.