Giter VIP home page Giter VIP logo

Comments (10)

strongh avatar strongh commented on July 17, 2024

hmmm... using alter-var-root essentially like you did, (alter-var-root (var test-fn) memo-redis) worked for me in a toy example. So it seems like that's a promising strategy, but I have a couple questions for you.

One thing is that it's important to execute the alter-var-root very early on in your app, before there are many calls to the fn which is being memoized. When exactly do you call alter-var-root?

The other thing is that redis memoization won't necessarily increase your app performance, so no change in performance doesn't mean it isn't working. Can you check to see whether there are redis interactions?

from crache.

ccfontes avatar ccfontes commented on July 17, 2024

This is my exact use case:

(alter-var-root (var f-memo) (fn [_] (memo-redis f)))

because the function is already memoized with core.memoize in the library, I have to use alter-var-root like that.

Answering your questions: I call alter-var-root in -main, which shouldn't be a problem because those functions are used after the app has started up, triggered by the user and there is an obvious performance issue, because I was getting up to 10x faster times when just using core.memoize. A typical use without memoization would take 40 seconds, but only 4 seconds with memoization. This is impossible to go unnoticed. I changed the app to only use the alter-var-rooted fns and there is write activity in the redis-server logs. Maybe the problem is reading back? I have a lot of the inputs/outputs in japanese characters. Is it maybe some encoding problem?

from crache.

strongh avatar strongh commented on July 17, 2024

Do you see redis GET commands?

At this point I would recommend putting together a reproducible test case... I've tried to test your usage with this gist:

https://gist.github.com/strongh/2055df89ff041915f855

Which works for me, in the sense that the core.memoized function is replaced by the redis-memoized version.

from crache.

ccfontes avatar ccfontes commented on July 17, 2024

@strongh thanks for taking this time!
I saw your gist. I don't have any GET commands in the window where redis-server is running. I have only writes. I show below an example of those logs:

[66942] 24 Sep 19:32:53.004 * 1 changes in 20 seconds. Saving...
[66942] 24 Sep 19:32:53.005 * Background saving started by pid 87190
[87190] 24 Sep 19:32:55.221 * DB saved on disk
[66942] 24 Sep 19:32:55.289 * Background saving terminated with success

I should note that memoization with memo-redis works in that app session. Just when I restart, the state isn't recovered.

I'm going to fiddle with this a little more and if I don't come up with a solution, I'll try to create a reproducible test case.

from crache.

ccfontes avatar ccfontes commented on July 17, 2024

@strongh I can't even get those GET commands with your own gist, so I don't know if reproducing this issue with my own code is relevant. After running the app twice (means exiting and starting the REPL again), I get different rand sequences.

I assume the function signatures are being accurately identified.

from crache.

strongh avatar strongh commented on July 17, 2024

You should be able to see the redis activity using redis-cli monitor, do you see any GETs there?

The per-session memoization is the default behavior. I've just pushed (and deployed to clojars) changes which should let you pass a :key-prefix into memo-redis. Setting that option should make that the cache use the same redis key each time it starts, as opposed to generating random keys each time.

from crache.

strongh avatar strongh commented on July 17, 2024

@ccfontes after actually trying out my change i realized that i hadn't done it correctly. i've had to redeploy to clojars again, but this time i checked to make sure that the new :key-prefix option works.

from crache.

ccfontes avatar ccfontes commented on July 17, 2024

@strongh thanks a lot again. Just curious, what was the use case for a redis backed memoization without being able to use the saved memory in the next session?

About my experiment with this new version and using :key-prefix, it consisted in the processing of a file:

  • without memoization → ± 100 seconds
  • with memo-redis first time → ± 43 seconds
  • with memo first time → ± 43 seconds
  • with memo-redis second time → ± 21 seconds
  • with memo second time → 4 seconds

After restart REPL (this part only applies to memo-redis):

  • with memo-redis first time → ± 32 seconds
  • with memo-redis second time → ± 23 seconds

Even though clearly redis-memo is working, it's still 5 times slower than memo. The alter-var-root fns are actually the ones that make most of the contribution to the gains in performance because I tested them in isolation also and times changed very little. I don't know what's happening here, but if I had to guess, I would say there are two problems:

  • data loss when encoding/decoding from persisted memory
  • bigger overhead for accessing cache in memo-redis compared to memo

I remember yet again my data is composed of Japanese characters.

Did you benchmark memo-redis against memo?

from crache.

strongh avatar strongh commented on July 17, 2024

Honestly it's been a while since I've used crache... but I believe I was using the TTL version of the memoization (for which core.memoize has no analog). No I've never benchmarked against memo. In my past application it was moving relatively small amounts of data to a local redis server, and the latency was in the milliseconds or perhaps tens of milliseconds at most.

I'm a bit shocked that a core.memoized function would take 4 seconds to return the second time (I assume that your inputs are the same each time).

I doubt that the difference in performance between core crache is related to Japanese characters in your data.

Depending on your application, you could consider having 2 layers of memoization; the local in-memory core.memoize, as well as the crache.memo for keys not in the first cache.

Crache will absolutely be slower than the core equivalents. It's performing serialization and deserialization, and possibly communicating over a network. Is your redis server co-located with your app?

The first optimization I'd consider is serialization. Currently (de)serialization is done by pr-str and read-string, which I doubt are terribly performant.

At any rate... it sounds like we should close this issue since the original question was resolved. Please feel free to open a new issue if you're interested in improving the performance. If you do, please include a little more information about your use case.

from crache.

ccfontes avatar ccfontes commented on July 17, 2024

I'm a bit shocked that a core.memoized function would take 4 seconds to return the second time (I assume that your inputs are the same each time).

It's always the same file in the second case. Even when it's not the same file, it will take only up to 10 seconds.

I'm running the redis server co-located with my app.

I'm going to open another issue and continue this discussing there.

from crache.

Related Issues (6)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.