clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
2020-11-05T03:59:41.133700Z

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

2020-11-05T16:29:22.137Z

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

tugh 2020-11-05T16:35:52.138200Z

i wouldnt say that it is too complex. im also curious about different ways to do it

2020-11-05T16:37:49.139400Z

is there a conventient thing to ingest a deps.edn into a running repl and use pomegranate to add all the dependencies ?

2020-11-05T16:39:01.139500Z

perhaps i make both dates and filter by the ones in the past

2020-11-05T16:39:23.139700Z

I'm also curious if the new fancy java-time has an easier time of this

seancorfield 2020-11-05T17:49:33.140900Z

@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

seancorfield 2020-11-05T17:50:02.141500Z

(I use this all the time to add new libs into my REPL started with clj)

2020-11-05T18:01:52.142400Z

ahh neet, i appreciate the name as well !

dharrigan 2020-11-05T18:03:08.142500Z

(let [this-morning (t/today-at 8 15)]
  (if (t/before? (t/now) this-morning)
    this-morning
    (t/plus this-morning (t/days 1))))

dharrigan 2020-11-05T18:03:11.142700Z

bit shorter 🙂

emccue 2020-11-05T21:47:53.144400Z

I have an idea - one moment

emccue 2020-11-05T21:53:35.144600Z

(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))))))

🙂 1
emccue 2020-11-05T21:53:49.144800Z

@arthur how does that look?

emccue 2020-11-05T21:55:26.145Z

i haven't run it and might have fudged the types, but that i used loop recur so

Ben Sless 2020-11-05T21:58:15.146200Z

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

alexmiller 2020-11-05T22:00:57.146700Z

Effects as opposed to what?

Ben Sless 2020-11-05T22:02:36.147600Z

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 invokestatic

Ben Sless 2020-11-05T22:03:49.148500Z

Just 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

alexmiller 2020-11-05T22:04:02.148800Z

the important question for performance is what the bytecode compiles to

borkdude 2020-11-05T22:04:44.149200Z

maybe the JVM could also optimize that bytecode internally?

alexmiller 2020-11-05T22:04:55.149700Z

it definitely can

Ben Sless 2020-11-05T22:05:06.150Z

I guess the JIT does that, but examining it is not trivial

alexmiller 2020-11-05T22:05:31.150500Z

there are jvm options to dump the compiled (and recompiled) assembly as it works

alexmiller 2020-11-05T22:06:24.151Z

so examining it is actually not that hard (although I don't have that set of options at hand)

Ben Sless 2020-11-05T22:06:55.151300Z

I'd have to examine assembly at that point?

alexmiller 2020-11-05T22:07:06.151500Z

yes

alexmiller 2020-11-05T22:07:24.152100Z

I mean, if you care about this level of performance, that's the part that matters

👍 1
alexmiller 2020-11-05T22:08:51.152800Z

https://wiki.openjdk.java.net/display/HotSpot/PrintAssembly

🙏 1
alexmiller 2020-11-05T22:10:16.153900Z

I've done this in the past for very specific questions and found it tractable to understand

Ben Sless 2020-11-05T22:10:27.154Z

There's also the question of how well that mixes with the JVM when it's under pressure

Ben Sless 2020-11-05T22:10:31.154200Z

Thanks for the directions

alexmiller 2020-11-05T22:11:00.154800Z

if you mean how well the printing works, you can filter to just what you care about

Ben Sless 2020-11-05T22:11:24.155700Z

No, I meant load/store instructions when the caches are busy

alexmiller 2020-11-05T22:12:30.156500Z

for example above that's all local so I'm not sure how much the cache would even be be involved?

Ben Sless 2020-11-05T22:13:05.157200Z

That's the problem with a contrived example. But thinking of a more real-world example with references, I assume they would be

Ben Sless 2020-11-05T22:13:37.157700Z

I won't waste more of your time with it, these are mostly idle thoughts for now

alexmiller 2020-11-05T22:14:00.158100Z

generally, there are probably a lot more important things to care about wrt perf than this

Ben Sless 2020-11-05T22:14:07.158300Z

exactly

Ben Sless 2020-11-05T22:14:25.158700Z

But sometimes you find yourself decompiling functions at midnight out of curiosity

borkdude 2020-11-05T22:30:53.160200Z

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 work

dharrigan 2020-11-05T22:30:54.160300Z

The Midnight Train To De-Compliation City?

dharrigan 2020-11-05T22:33:50.160500Z

:shocked_face_with_exploding_head:

2020-11-05T22:37:18.160900Z

if the code doesn't run enough it never gets compiled

borkdude 2020-11-05T22:40:09.161500Z

good point. if I make a loop around it, I get: Could not load hsdis-amd64.dylib; library not loadable; PrintAssembly is disabled

2020-11-05T22:40:10.161600Z

you may want -XX:+PrintCompilation

2020-11-05T22:40:32.162Z

that is because -XX:CompileCommand depends on a java agent or something

2020-11-05T22:40:54.162300Z

(the missing dylib thing)

2020-11-05T22:42:16.162500Z

https://wiki.openjdk.java.net/display/HotSpot/PrintAssembly may be useful

2020-11-05T22:43:12.162800Z

oh, hah, already been linked

borkdude 2020-11-05T22:47:03.163100Z

I'm using the other option to restrict the output to one method. it works now

borkdude 2020-11-05T22:50:16.163200Z

0x0000000119326418: je     0x0000000119326431  ;*iload_0
                                                ; - Example::foo@0 (line 4)

  0x000000011932641e: inc    %esi
  0x0000000119326420: inc    %esi
  0x0000000119326422: mov    %rsi,%rax

ghadi 2020-11-05T23:01:44.165800Z

Speaking of, has anyone done any comparitive measurements of Clojure programs on arm64 vs x86-64? interested in workloads on Amazon Graviton2

emccue 2020-11-05T23:36:05.166400Z

@dharrigan You laugh, but its runtime is O(172800)

emccue 2020-11-05T23:36:17.166600Z

technically still constant time