Hum.... Not sure a Record uses any less memory then a map. I'd ignore the "fear of maps using more memory" and just parse the XML into maps
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 thisi wouldnt say that it is too complex. im also curious about different ways to do it
is there a conventient thing to ingest a deps.edn into a running repl and use pomegranate to add all the dependencies ?
perhaps i make both dates and filter by the ones in the past
I'm also curious if the new fancy java-time has an easier time of this
@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
)
ahh neet, i appreciate the name as well !
(let [this-morning (t/today-at 8 15)]
(if (t/before? (t/now) this-morning)
this-morning
(t/plus this-morning (t/days 1))))
bit shorter 🙂
I have an idea - one moment
(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))))))
@arthur how does that look?
i haven't run it and might have fudged the types, but that i used loop recur so
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
maybe the JVM could also optimize that bytecode internally?
it definitely can
I guess the JIT does that, but examining it is not trivial
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'd have to examine assembly at that point?
yes
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
Thanks for the directions
if you mean how well the printing works, you can filter to just what you care about
No, I meant load/store instructions when the caches are busy
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
I won't waste more of your time with it, these are mostly idle thoughts for now
generally, there are probably a lot more important things to care about wrt perf than this
exactly
But sometimes you find yourself decompiling functions at midnight out of curiosity
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 workThe Midnight Train To De-Compliation City?
:shocked_face_with_exploding_head:
if the code doesn't run enough it never gets compiled
good point. if I make a loop around it, I get: Could not load hsdis-amd64.dylib; library not loadable; PrintAssembly is disabled
you may want -XX:+PrintCompilation
that is because -XX:CompileCommand depends on a java agent or something
(the missing dylib thing)
https://wiki.openjdk.java.net/display/HotSpot/PrintAssembly may be useful
oh, hah, already been linked
I'm using the other option to restrict the output to one method. it works now
0x0000000119326418: je 0x0000000119326431 ;*iload_0
; - Example::foo@0 (line 4)
0x000000011932641e: inc %esi
0x0000000119326420: inc %esi
0x0000000119326422: mov %rsi,%rax
Speaking of, has anyone done any comparitive measurements of Clojure programs on arm64 vs x86-64? interested in workloads on Amazon Graviton2
@dharrigan You laugh, but its runtime is O(172800)
technically still constant time