Fork me on GitHub
Stel Abrego08:04:39

Hey is there any weirdness with trying to reference an interface with a period in it like Application.OnActivate? For the life of me I can't figure out how to access interface from Clojure.


The dot is not in its name. The name of the interface is OnActivate, but the interface is defined within a class named Application. Try using $ instead of that particular ..

🙏 1
Stel Abrego08:04:49

Omg thank you so much! Just had to (:import ch.bailu.gtk.gio.Application$OnActivate) and refer to it as Application$OnActivate


I found something interesting. Can someone explain this behaviour?

(= (clojure.instant/read-instant-timestamp "2021-02-01T00:00:00Z")
   (clojure.instant/read-instant-timestamp "2021-02-01T00:00:00Z")) 
; true

(= #inst "2021-02-01T00:00:00.000000000-00:00"
   #inst "2021-02-01T00:00:00.000000000-00:00") 
; true

(= (clojure.instant/read-instant-timestamp "2021-02-01T00:00:00Z")
   #inst "2021-02-01T00:00:00.000000000-00:00") 
; false

;; if I switch the order, it evaluates to true.
(= #inst "2021-02-01T00:00:00.000000000-00:00"
   (clojure.instant/read-instant-timestamp "2021-02-01T00:00:00Z"))
; true


(= (hash (inst/read-instant-timestamp "2021-02-01T00:00:00Z")) (hash #inst "2021-02-01T00:00:00.000000000-00:00"))
; true 
and also
(.equals #inst "2021-02-01T00:00:00.000000000-00:00" (inst/read-instant-timestamp "2021-02-01T00:00:00Z"))
is true


The results of #inst ... and (clojure.instant/read-instant-typestamp ...) are objects of different classes.


why does switching the order work then? :thinking_face:

;; if I switch the order, it evaluates to true.
(= #inst "2021-02-01T00:00:00.000000000-00:00"
   (clojure.instant/read-instant-timestamp "2021-02-01T00:00:00Z"))
; true


Because the classes have different implementation of .equals.


Of course that how it is, but the question is whether that’s the desired solution. I feel this should be considered a bug, as it can throw some nasty surprises.


Not sure what you mean. A Timestamp is a Date but a Date is not a Timestamp. It's regular inheritance at play. And one has to use clojure.instant/read-instant-timestamp quite deliberately - that's not something you do by accident. And its docstring hints at the fact that by default #inst is not read as Timestamp. And that's also documented here:


So a Date can be compared with a Timestamp, but not vice versa. You are right about the deliberate usage, the caller should know what they are getting into. Thanks.

Nom Nom Mousse12:04:02

What is the best way to check if a file is binary from the JVM?

Nom Nom Mousse12:04:08

Perhaps file -I -b and check that the result does not say .* charset=binary

Nom Nom Mousse12:04:53

First attempt:

(defn is-binary? [f]
  (let [stdout (:out ( "file" "-I" "-b" f))
        charset (second (re-find #"charset=(.*)" stdout))]
    (= "binary" charset)))

Wanja Hentze12:04:01

When exactly is a file "binary"?

Wanja Hentze12:04:18

There are many ways to answer that question

Wanja Hentze12:04:54

One program's EBCDIC text file is another's binary file.

Jeffrey Bay16:04:51

hey all - we're doing some benchmarking on small pieces of code related to performance, which we have a lot of tools for, but a related area of concern is memory allocation and GC - are there any benchmark type tools out there that will run an expression over and over and then give a report on how much workload for GC it threw off? Ideally - how much memory allocated in how many objects, per invocation? something like that?




I second async profiler. There's also clj-memory-meter. Then allocation profiling in popular profilers like YourKit. And maybe enabling and analysing GC logs

Jeffrey Bay17:04:43

familiar with several of these tools - but we're looking for a tool more specifically like quick-bench, which can be invoked in code and give a summary answer, as opposed to a profiler that is more of an analysis tool - i.e., comparison vs exploration. async profiler looks like a very interesting profiler tool, esp open source, but not quite in the exact use case I'm reaching for here.


The criterium approach looks too simplistic

Ben Sless20:04:33

What's wrong with async profiler? You can profile an expression and run it multiple times,getting a pretty accurate view of allocations


You can get the stats you want through jmh with the gc profiler. jmh-clojure provides a useful interface


And it lets you do allocation profiling

Jeffrey Bay23:04:47

super neat, both jmh-clojure and clj-async-profiler look like very strong possibilities!


Just note that you will be profiling the whole jvm not necessarily only your expression- so make sure there's nothing else significant running in the same process


just now wanted to ask exactly this question Thanks Universe, and @U03A0EGF82E 🙂

Ben Sless15:04:15

With clj-async-profiler you can wrap whatever expression you're interested in with dotimes and let it spin, collecting plenty of samples. You can profile CPU or memory allocation. It's very informative


Sure, but you are still profiling the whole jvm - there's no special magic. Still, You will likely get good results if you have an isolated environment

Ben Sless18:04:59

True, although it's better to profile an entire application to get a realistic image


What do you mean by profiling the whole JVM? The resulting flame-graph is filtered down to only your enclosed call-stack scope, so you do get to see only the part you're concerned with.

Ben Sless18:04:03

He's right in that you're affected by the whole JVM even if you're only running the sampling process for the duration of your run.


I'm not sure what that means? Like, you could argue I'm also profiling my whole computer, if I've got some protein folding going on in the background, and a big file copy, than my timings will be affected, but I'm still getting the profile of my function as it is running on my computer


You can of course see what your function did but you will also see other threads (cpu) or allocations completely unrelated to your function.

Jeffrey Bay19:04:52

our axe was more about repeatability and repl/ease of use, so we're not super worried about the rest of the JVM in our use case - no other work going on really


Yeah, as I said, it's most likely gonna be fine 🙂.


Hum... are you sure? I haven't done an allocation profile in a while, but when I do a CPU one, it only shows me things that spawned from the function


It seems to all be filtered on the stack of the function. So it doesn't show anything unrelated.


Like isn't that the whole point of the flame graph? You can see within a function what is taking time.


No, it doesn't work that way. Async Profiler typically profiles the whole process. Although you can filter specific methods, etc. - but that's not what clj-async-profiler is doing When you look at the code, you can see it simply calls start and stop - no magic filtering is happening:


The filtering is on the render, the flame graph is displayed and shows you each functions and their stack.


Maybe we're talking past each other. My point is that you get to see exactly how much time the function took, and of that time how much time the functions inside it took, etc. So you can see clearly the time/allocations related to your function and yours only.


Are you saying that's not the case? That the time you see your function took in the resulting flame graph actually includes compute time from other unrelated things?