Fork me on GitHub
#clojurescript
<
2024-03-20
>
Harel Gelberg10:03:12

Hey šŸ™‚ I'm in need for a high performance LRU cache solution and looking at https://github.com/burbma/cljs-cache/tree/master wondering if I should be using that. My question is if the immutability (creating a new cache every hit/miss) + using an atom (which seems like the default way) is slower than creating some dynamic variable which I can just change in place. Will it even gain performance improvements? Are there risks which I don't know about for the dynamic variable solution?

thomas11:03:34

maybe a silly question... but have you already benchmarked it and established cljs-cache is not fast enough/bottleneck?

Harel Gelberg12:03:22

Not a silly question at all šŸ˜… Two things : 1. I'm not sure how can I bench mark such a thing. I understand that benchmarking it in the REPL/tests is not a good way because when running prod environment things tend to be very different. 2. I preemptively tried to predict if it can be a bottleneck (with knowledge other people have) so I won't waste time on it.

thomas12:03:38

1. yes, I guess this is the case... 2. fair enough... and the only way of knowing for sure is actually measuring it. šŸ¤· so you might need to prototype it. (and then find out it was not needed after all)

thomas12:03:54

so I haven't actually given you an answer, sorry.

Nundrum13:03:13

I think maybe there's some misunderstanding about "creating a new cache" here? The link below explains why that still performs well. Yes, you might be able to get something faster mutating in place. And how much faster might depend on how often evictions happen? IDK, but Riemann uses core.cache and is pretty darn fast. https://hypirion.com/musings/understanding-persistent-vector-pt-1

p-himik15:03:24

You should definitely not guess what the bottleneck is. Just measure it.

Michaƫl Salihi15:03:35

Hi ! Seems this interop is little bit challenging, right?

size({
  apply({rects, elements}) {
    Object.assign(elements.floating.style, {
      width: `${rects.reference.width}px`,
    });
  },
});
Any idea how to access this desctrured apply fn in size params please?

p-himik15:03:03

Not sure what you mean by "destructured apply". What's being done is:

(size #js {:apply (fn [^js x]
                    (let [rects (.-rects x)
                          elements (.-elements x)]
                      (js/Object.assign (-> elements .-floating .-style)
                                        #js {:width (str (-> rects .-reference .-width) "px")})))})

p-himik15:03:52

And if size is a function where you need to access that :apply function:

(defn size [^js x]
  (let [apply (.-apply x)]
    ...))

Michaƫl Salihi15:03:39

OK nice! Thank you, this more clear right now.

šŸ‘ 1
Michaƫl Salihi16:03:54

As I like using applied-science/js-interop lib for interop, here the final result that I use:

(size #js {:apply (j/fn [^:js {:keys [rects elements]}]
                    (j/assoc-in! elements
                                 [:floating :style :width]
                                 (str (.. rects -reference -width) "px")))})]}))
Thank again!