This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-11-05
Channels
- # announcements (1)
- # babashka (6)
- # beginners (31)
- # calva (23)
- # cider (38)
- # clj-kondo (98)
- # cljs-dev (3)
- # clojure (56)
- # clojure-australia (2)
- # clojure-europe (14)
- # clojure-italy (1)
- # clojure-nl (2)
- # clojure-spec (17)
- # clojure-uk (27)
- # clojurescript (45)
- # code-reviews (1)
- # core-async (26)
- # core-logic (10)
- # cursive (11)
- # data-science (9)
- # datomic (7)
- # deps-new (4)
- # devcards (1)
- # emacs (4)
- # etaoin (2)
- # fulcro (14)
- # jobs (1)
- # kaocha (1)
- # leiningen (50)
- # malli (3)
- # parinfer (1)
- # pathom (7)
- # reitit (4)
- # remote-jobs (1)
- # reveal (45)
- # shadow-cljs (59)
- # sql (97)
- # tools-deps (1)
- # uncomplicate (4)
- # vim (18)
I have this overly complex method in a project for finding the next time it's 8:15 am. (the result is applied to a timezone later)
(defn the-next-8-15-am-localtime []
(let [now (t/now)
this-morning (t/date-time (t/year now) (t/month now) (t/day now) 8 15)
tomorrow-morning (t/plus
this-morning
(t/days 1))]
(if (t/before? now this-morning)
this-morning
tomorrow-morning)))
using clj-time (java-time is not available in this project)
I strongly suspect there is a more proper way to do this(let [this-morning (t/today-at 8 15)]
(if (t/before? (t/now) this-morning)
this-morning
(t/plus this-morning (t/days 1))))
(defn the-next-8-15-am-localtime []
(loop [now (t/now)]
(if (and (= 8 (hour now))
(= 15 (minute now)))
(t/date-time now)
(recur (t/plus now (t/seconds 1))))))
@U11EL3P9U You laugh, but its runtime is O(172800)
I could spell out the math as well in the initial date creation time. which feels like reinventing the library
is there a conventient thing to ingest a deps.edn into a running repl and use pomegranate to add all the dependencies ?
@arthur You can use the add-lib3
branch of t.d.a for that -- see my dot-clojure file: https://github.com/seancorfield/dot-clojure/blob/develop/deps.edn#L167-L190
(I use this all the time to add new libs into my REPL started with clj
)
What are the effects of binding expressions in let
on the JVM in terms of performance? I see they decompile to store and load instructions, but how significant are they? I'm guessing there are also differences between loading primitives and references, and how much throughput is going through the CPU's caches
Effects as opposed to what?
let's take this contrived example:
(defn foo [^long a]
(let [a (inc a)
a (inc a)
a (inc a)
a (inc a)
a (inc a)
a (inc a)
a (inc a)
a (inc a)]
a))
(defn bar [^long a]
(-> a
inc inc inc inc
inc inc inc inc))
One stores and loads a long constantly, while the other only calls invokestaticJust a snippet of the bytecode:
27: invokestatic clojure/lang/Numbers.inc:(J)J
30: lstore a
32: lload a
linenumber 7
34: invokestatic clojure/lang/Numbers.inc:(J)J
vs
16: invokestatic clojure/lang/Numbers.inc:(J)J
linenumber 2
19: invokestatic clojure/lang/Numbers.inc:(J)J
the important question for performance is what the bytecode compiles to
it definitely can
there are jvm options to dump the compiled (and recompiled) assembly as it works
so examining it is actually not that hard (although I don't have that set of options at hand)
I mean, if you care about this level of performance, that's the part that matters
I've done this in the past for very specific questions and found it tractable to understand
There's also the question of how well that mixes with the JVM when it's under pressure
if you mean how well the printing works, you can filter to just what you care about
for example above that's all local so I'm not sure how much the cache would even be be involved?
That's the problem with a contrived example. But thinking of a more real-world example with references, I assume they would be
generally, there are probably a lot more important things to care about wrt perf than this
I'm trying to get assembly output for this simple example:
borkdude@MBA2015 /tmp $ cat Foo.java
public class Foo {
public static int foo(int i) {
i = i + 1;
i = i + 1;
return i;
}
public static void main(String [] args) {
System.out.println(foo(1));
}
}
borkdude@MBA2015 /tmp $ javac Foo.java
borkdude@MBA2015 /tmp $ java -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:CompileCommand="print Foo.foo" Foo
CompileCommand: print Foo.foo
3
but somehow it doesn't workgood point. if I make a loop around it, I get: Could not load hsdis-amd64.dylib; library not loadable; PrintAssembly is disabled