This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-08-30
Channels
- # announcements (1)
- # beginners (94)
- # calva (12)
- # cider (5)
- # cljdoc (4)
- # cljs-dev (4)
- # clojure (170)
- # clojure-austin (2)
- # clojure-dev (45)
- # clojure-germany (53)
- # clojure-italy (20)
- # clojure-nl (6)
- # clojure-spec (25)
- # clojure-uk (242)
- # clojurescript (161)
- # cursive (16)
- # data-science (3)
- # datomic (20)
- # defnpodcast (6)
- # emacs (40)
- # events (1)
- # fulcro (80)
- # funcool (46)
- # jobs (1)
- # leiningen (23)
- # liberator (2)
- # lumo (43)
- # mount (3)
- # off-topic (21)
- # onyx (1)
- # pedestal (15)
- # re-frame (23)
- # reitit (4)
- # schema (1)
- # sfcljs (1)
- # shadow-cljs (167)
- # spacemacs (1)
- # tools-deps (21)
- # yada (2)
it is weird that the compiler seems to store symbols in clojure.lang.AFn
fields; does anybody know if that serves a purpose?
it's my observation when javap -c
ing some generated class files
Closed over vals get stored in fields
Is that what you’re seeing?
this is a literal used in the function
so it's stored in static init {}
I annotated the fields; const__4
is an AFn
for storing a symbol
I see that in another class as well
I doubt it causes any problems, it's just weird
"sometimes the clojure compiler is weird" is a perfectly good answer 🙂
(to be clear, I would have expected either of clojure.lang.Symbol
or Object
)
this whole class just represents the call (commute @#'*loaded-libs* conj 'user.empty-ns)
Oh, that’s just filling the constant pool to set up static initialization
sure but why AFn
for a symbol?
@gfredericks because the compiler emits either Var/AFn/String/Keyword or Object, and a symbol happens to be an AFn
Could some checkcasts be eliminated for these fields?
Maybe the jvm does a good job of optimizing them?
Okay cool well anyhow that "explains" the AFn thing well enough
@bronsa they're actually free in hot code where there is runtime type profiling. They are not free inside <clinit>, which is by definition always cold
I can't imagine the amount of checkcasts in <clinit>
causing performance issues tho, but I've never profiled it
getting the Symbol.intern() and RT.var() calls out of <clinit>
entirely would be a much larger payoff
how would you get them out? do them lazily the first time?
ah right yeah cool
@ghadi > they’re actually free in hot code where there is runtime type profiling Is this based on some callsite caching? Can it be costly if the site is megamorphic etc?
Or perhaps that doesn’t apply here. Just curious. I’ve often wondered what the overhead of checkcast
may be.
@mikerod if you have an AFn on the stack, and it checkcasts to IFn, that can be completely eliminated if you have Object on the stack, and then a checkcast to IFn, the JIT can profile and specialize -- then do on-stack replacement if the assumptions don't work out
I have run into cases in hot numeric loops where there was a measurable difference that seemed attributable to checkcast (but this experience probably dates to jdk 6 or maybe 7 era)
This was comparing bytecode generated by Java vs Clojure which was nearly identical
I guess if there are too many checkcast
all over though, it adds bytecodes which increases method size, which eventually can affect inlining stuff I guess
yeah, so much optimization goes into each jvm version though that who knows if I could replicate that today