This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-03
Channels
- # bangalore-clj (1)
- # beginners (104)
- # boot (30)
- # braveandtrue (1)
- # cider (6)
- # cljs-dev (95)
- # cljsjs (16)
- # cljsrn (3)
- # clojure (106)
- # clojure-italy (15)
- # clojure-nl (2)
- # clojure-norway (3)
- # clojure-russia (1)
- # clojure-spec (40)
- # clojure-uk (53)
- # clojure-ukraine (1)
- # clojurescript (200)
- # code-reviews (2)
- # cursive (1)
- # datascript (3)
- # datomic (32)
- # editors (28)
- # gorilla (6)
- # graphql (8)
- # hoplon (1)
- # jobs (8)
- # jobs-discuss (5)
- # jobs-rus (1)
- # keechma (13)
- # leiningen (5)
- # luminus (3)
- # lumo (53)
- # off-topic (5)
- # om (5)
- # om-next (1)
- # onyx (56)
- # parinfer (7)
- # protorepl (22)
- # re-frame (47)
- # reagent (37)
- # remote-jobs (1)
- # ring-swagger (9)
- # specter (7)
- # vim (14)
- # yada (30)
don't wana get political, but the name of a certain POTUS comes to mind. might work. or not.
Anyone know how I can simplify this any further? Feels wonky
(when format
(when data-id (str "/" data-id))
(str "." format))
No, also when it is true. When format is falsey, you get nil
, else you get (str "." format)
yes but only when format is truthy. There are cases when format is truthy and data-id is falsey
no need for the if āā because the nil when passed to string will return the same thing
Thanks for the ā`when` always returns the result of the last expression it hasā
does anyone have experience of using the nebula.clojure gradle plugin to build a clojure project?
beginner performance question: I want to lazily process a collection of numbers but my code needs the sum of all the numbers so it can do its job so unless there is some clever math trick that I haven't thought of it looks like I have to populate the entire collection
feed a reduce with a lazy-seq
you donāt need to realize more than one of the inputs at a time
(reduce + 0 (map some-processing-fn input))
see also transduce if you need to make it perform slightly better
(transduce (map some-processing-fn) + 0 input)
- almost the same, less wasteful internals
(but here the difference is very minor)
sorry, every time I tried to write this gist someone would come up and interrupt me with work. This gist might illustrate what I'm trying to do a little bit better https://gist.github.com/gdeer81/0a3254afa21c853c87a0635e09063504
canāt you add an extra data slot in your accumulator and do the sum in the reduce?
that avoids needing to hold onto the head of coll, which is a problem
so instead of your acc being []
it would be {:coll-sum 0 :result []}
and you update both on each iteration
oh wait do you need to know that sum before any item is processed?
yeah, thatās trickier
but is coll always just the numbers? if so just use range and call it each place you need it
instead of holding onto it in one place
the numbers are cheap enough to just generate them twice using range - the extra work to put them into a collection you reuse (which range wonāt do inside reduce btw) is more expensive than getting the numbers is
(which is why to use range instead of iterate)
right, call range in both places
never bind the numbers
perhaps make a thunk like #(range 1 (inc n))
and call it in each place you currently use coll
that way you arenāt holding onto head, which is the problem with huge n here
also, for certain values of āhugeā you might need +'
and *'
to replace +
and *
so I've done all that and I've even added some type hints and it's only shaved about 400 milliseconds off the processing time
+' and *' slow down the math - they would be for correctness on numbers too big for a Long
I feel like I'm missing something important about the problem that is the key to not having to code it like this
well, thereās always not trying to do number crunching in fp, some people swear by that one
but in all seriousness I bet thereās some more simple stuff we can do - try checking for warn-on-boxed for example http://insideclojure.org/2014/12/15/warn-on-boxed/
but beyond a certain point it does get easier to do your number crunching in java and use interop compared to the tricks needed to get clojure to behave
@gdeer81 The sum of a series of numbers from 1-n is half of n squared minus n or (/ (* n (dec n)) 2)
@seancorfield I knew there was a magic formula I was missing, thank you š¼
Glad my BSc in Math from '83 is useful for something š
What sort of timings are you getting for what sort of numbers?
@seancorfield @gdeer81 i believe you're misremembering the formula:
boot.user=> (reduce + (range 1 101))
5050
boot.user=> (/ (* 100 (dec 100)) 2)
4950
boot.user=> (* (inc 100) (/ 100 2))
5050
Ah, I'd already incremented n
to produce the range
that @gdeer81 needed
I refactored after that so I have (/ (* n (inc n)) 2)
now so we agree š
@seancorfield I wonder if it would speed things up at all to turn that into into / filter
since itās effectively that
also, if it remains a reduce, it should speed up a little if you hold onto the second arg to the fn and reuse it instead of creating another vector
but the into/filter transducer would probably be more straightforward anyway
(into [] (filter (fn [[^long num1 ^long num2]] (= (- coll-sum num1 num2) (* num1 num2)))) (for ...))
Duh, don't need the reduce
at all -- could use :when
in the for
...
oh! nice
That's 650ms for 3003
wait what about the incsā¦
I think they should be taken out of the vector now
Doesn't make much difference to the timing at that point
And if you take out the doall
then it's lazy as well which might be useful. I just did that for timing.
(I ran it with :warn-on-boxed
to be sure there was no boxing -- there wasn't)
itās amazing how many warnings spill out just removing the ^long annotation on line 1
Ah, I should have (set! *unchecked-math* :warn-on-boxed)
above the function! I use it so rarely I forget how...
That's better... down to 283ms for 3003!
Updated the snippet...
So I think that's down from 4 seconds for the original I saw to sub-300ms?
I think @gdeer81 has gone home for the evening...
@noisesmith Can you speed that up further?
heh, itās all good, the process is informative for us all anyway
my first few tries are not improving it
haha, binding inc n
to a new symbol and reusing it instead of incrementing inline slows the code down - just a bit, but less than the std-deviation as calculated by criterium