This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-04-24
Channels
- # aws-lambda (1)
- # beginners (99)
- # boot (46)
- # cider (8)
- # cljs-dev (20)
- # cljsrn (37)
- # clojure (189)
- # clojure-dev (22)
- # clojure-dusseldorf (28)
- # clojure-italy (1)
- # clojure-russia (28)
- # clojure-spec (10)
- # clojure-uk (33)
- # clojurebridge (1)
- # clojurescript (64)
- # core-matrix (2)
- # css (3)
- # cursive (3)
- # datascript (34)
- # datomic (101)
- # defnpodcast (2)
- # dirac (5)
- # events (1)
- # funcool (3)
- # ldnclj (1)
- # lumo (11)
- # mount (1)
- # off-topic (95)
- # pedestal (2)
- # perun (10)
- # re-frame (3)
- # reagent (6)
- # ring-swagger (4)
- # specter (102)
- # test-check (1)
- # untangled (1)
- # vim (8)
- # yada (17)
hare-brained idea to enhance emitted code for map / vector construction: pre-construct an array with all the literal parameters -- then fill in only the dynamic parameters at runtime
the type of code that could potentially be enhanced https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/analyzer.cljc#L1673-L1686
Would only really work for larger maps though, < 8 items it's probably faster to create a PersistentArrayMap from an array instead of create a map and add some things to it.
there's probably a heuristic/threshold involved for sure, but even for < 8 items / PAM, half your slots are probably literal keywords
you would System.arraycopy the half-filled array, finish filling it in, and pass it to PAM/create()
right, but how is that faster than creating an array and filling in the pointers?
It's "copy an array, write 8 pointers" vs "create an array, write 16 pointers"
i saw a recent john rose talk last night, and he said the bytecode for creating an array is boilerplatey and hard to do escape analysis on
it would be 1 opcode for the invoke instead of a crap ton for pushing ints and arraystores
well it seems like it'd be easy enough to hack in and benchmark.
I've thought of doing this in the past, but threw the idea out for the reasons I mentioned.
Never did benchmark it though
because the invokedynamic bootstrap method can only take constants/ldc as partial arguments
A crappy way to do it would be to print the "template" like "[:foo _ :bar _ :baz _]"
and c.c/read
it in the bootstrap method
ConstantDynamic "condy" is coming though! ... we'll have ldc
instructions that can take a bootstrap method
One clever thing to encode the constant parameters of the bootstrap method: write a bitmap in an int of the filled out slots, then write the representations of a subset of literal expressions, like string/keyword/long. Longs would be unambiguous, and keywords could be strings w/ a magic prefix. So e.g. a boostrap method with these params: 10101010 (int) "kwfoo" "kwbar" "kwbaz" 42 BootstrapMethod (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lclojure/lang/IPersistentMap ^ would result in a call site that took 4 arguments, and generated a map looking like:
{:foo arg1
:bar arg2
:baz arg3
42 arg4}
the bootstrap method would look something like:
bootstrap (Lookup caller, String name, MethodType mt, int bitmap, Object... args) {
Object[] template = new Object[Integer.bitCount(bitmap)];
.... insert the args into the array template
return ConstantCallSite(partial(fill_out_remaining(template, bitmap)));
}