Fork me on GitHub

How come RT.boundedLength doesn't check for Counted? Also it could be made more efficient for chunked sequences. Would potentially speedup apply

Alex Miller (Clojure team)16:01:57

it’s probably usually called with non-Counted instances, but feel free to make a ticket


bounded-lenght does that check in clojure


err, bounded-count

Alex Miller (Clojure team)16:01:01

as with any perf ticket, it is helpful to include test results that illustrate the perf improvement of the change when it helps and also any cases that have costs (adding an instanceof check will slow down the non-Counted case)

Alex Miller (Clojure team)16:01:17

yeah, that’s a totally different path I think


right, and what’s to note is that for bounded-count it’s not just a performance optimization, it changes the behaviour

Alex Miller (Clojure team)16:01:45

that’s also a fair thing to consider if same is true here


because it’s implemented as (if (counted? x) (count x) loop/recur) rather than (if (count x) (min (count x) bound) loop/recur)


(it surprised me a couple of times)

Alex Miller (Clojure team)16:01:42

yeah, you wouldn’t want that here


I see, that makes sense. I haven't dabbled on the Java side of clojure but I might run some tests at some point. It's very likely be worth it if the bound was high. Admittedly which is seldom. Usually people keep their fixed args to <5 or so.


All the apply/applyTo code is super old and could likely be sped up a bit. Maybe even use chunked sequences while plucking out the fixed arguments.


In CLJS I got it faster than Clojure, which made me check out the implementation...


Eg (apply a b c d xs) first builds up a bunch of Cons, just to later iterate over them for counting, then iterating over it again for plucking out the arguments. Then to finally call the fn.

Alex Miller (Clojure team)17:01:56

it wouldn’t surprise me if there were improvements to be made. considering the distribution of arg cases (obviously not uniform and weighted towards fewer) and actual class cases, it’s hard to predict overall impact

Alex Miller (Clojure team)17:01:28

to screen this I would want to understand what the distribution is in actuality both in terms of classes and size (usually I build a debugging patch that captures and records this info)

Alex Miller (Clojure team)17:01:36

and I would want to understand expected performance differences for some of the points in that space. For example, I expect ArraySeq, PersistentList, Cons etc to be common classes - how do each of those change in perf on invocation of different sizes, etc

Alex Miller (Clojure team)17:01:20

and then it’s useful to actually try something at an aggregate level to see if there is any observed perf difference in a real use case

Alex Miller (Clojure team)17:01:03

some hefty computation that involves a lot of invocation but little concurrency that can be easily re-run would be ideal


I see. I'm guessing that'd be a big project. Probably could use heuristics (`if getRequiredArity() < 3 fallback-to-naive-first-next()`) to not impact current performance baseline. But yeah, it's probably not as simple as in CLJS I guess 🙂

Alex Miller (Clojure team)17:01:55

yeah, that’s the kind of work I typically do for perf improvements in Clojure :)

Alex Miller (Clojure team)17:01:36

doing the case analysis and simple timings wouldn’t take that long and should suggest whether this is a good idea and how much additional effort to put into it

Alex Miller (Clojure team)17:01:40

adding additional checks has its own cost on inlining, so you want to minimize those too


A noob question: When do you do Java dev on Clojure, do you just have to recompile the entire project on every change or is there some smart way to stay in the REPL even after editing the java code?

Alex Miller (Clojure team)17:01:07

I think a check for Counted is likely fast and probably common enough to be worth doing

Alex Miller (Clojure team)17:01:40

I usually recompile. there are ways to do Java code reloading but I don’t really trust them, esp if trying to evaluate perf changes


got it. Thanks for your input. Appreciate it.

Alex Miller (Clojure team)17:01:31

you can do a full build of Clojure (Java + Clojure AOT) in about 15 s

Alex Miller (Clojure team)17:01:49

usually I spend a lot longer changing the code than that :)

Alex Miller (Clojure team)17:01:24

just mvn compile to rebuild


@rauh I use

compile-clojure () {
    pushd $HOME/src/clojure
    rm -rf target
    mvn install -Dmaven.test.skip=true


@bronsa Thanks for the snippet. Saved 🙂

Alex Miller (Clojure team)17:01:29

mvn install does a lot more work (packaging and deployment)

Alex Miller (Clojure team)17:01:46

I guess it depends how you expect to use it


yeah use install if you care about using the SNAPSHOT version from e.g. clj


Doesn't Java 9 introduce some Java compiler Interface? Just to code until the impl is working. Then proper compile for performance testing..

Alex Miller (Clojure team)18:01:02

I don’t know of anything new in java 9 for this - stuff has been there for a while to support hot code reloading. But in practical terms what you need to do to make that work is a lot more intrusive than just recompiling.