It's not a huge contributor but Class loading isn't free and Clojure could optimise it in a couple of places. I think with a couple of months effort in optimisation you might be able to get it down to 500ms for a simple "hello world". I'm doubtful you can get it much lower than that. TBH I'm not sure if the engineering effort would necessarily be worth it for many users.
I wanted to test dynamic loading and docker before I shared the article more broadly but here's the results from implementing prefetching in Clojure; https://junctionbox.ca/2018/01/04/clojure-class-prefetching.html It's a part of a series that I'm slowly plodding through as I have time. I hope to cover off the 4 items from the conclusion of this article; https://junctionbox.ca/2017/12/26/clojure-startup-walkthrough.html#conclusions Cheerio! Nathan On 26 January 2018 at 01:51, Timothy Baldridge <tbaldri...@gmail.com> wrote: > I would suggest everyone here read this document: https://dev.clojure. > org/display/design/Improving+Clojure+Start+Time It goes into a lot of > detail on prior work in this area, and I'd say the benchmarks on it should > be quite informative. > > But let me also go into a bit more detail into how CLJS differs from CLJ > in how it accesses global function definitions: > > In CLJs, clojure core contains a lot of definitions that look something > like this: > > clojure.core.conj = function () {... clojure.core.some_fn(...) . ....} > > The cost of creating that global function is then the cost of 2 lookups > (clojure in the global namespace, core in clojure), the creating of a JS > function object, and the assigning of that function to the core object. The > internal call to some_fn doesn't matter at load-time because of > Javascript's late binding. > > In the JVM this happens: > > 1) A class is loaded that implements the IFn or AFn interfaces > 2) The methods on this class must be loaded and the bytcode parsed, and > validated > 3) The static constructor on this method is run > 4) Inside the static constructor there are calls to find Vars. In the case > of the above function this would be a lookup to clojure.core.some_fn. This > is done for every var referenced by this function > 5) Any non-native constants must be new'd up. This includes hashmaps, > vectors, lists, keywords (which must be interned), symbols, etc. > 5) The clojure.core.conj var is created > 6) The contents of the var are set to the function that was loaded (and > new'd). Synchronization doesn't matter here as there are no other threads > that can see this Var. > 7) The metadata for the function is created. Most of the time this > includes creating a hashmap with at least 2-3 values. > 8) The metadata for the var is set. > > The systems in play here are completely different. So I re-state what I > said before: it's apples-to-oranges. > > But I'd love to see more benchmarks in this thread, so far we only have > opinions. > > > On Thu, Jan 25, 2018 at 9:37 PM, Timothy Baldridge <tbaldri...@gmail.com> > wrote: > >> >> If Var reification is part of the slowness of Clojure startup over >> Java's >> >> It's really not. If you completely removed vars from Clojure on the JVM, >> Clojure wouldn't be faster by any measurable amount. If someone has >> benchmarks that say that Vars themselves are the cause of Clojure JVM's >> slower startup, then I'd love to see those benchmarks, because there's most >> likely a serious flaw in the measurements. >> >> On Thu, Jan 25, 2018 at 9:34 PM, Didier <didi...@gmail.com> wrote: >> >>> Really, any comparisons between JS and JVM startup times are not useful >>>> at all. >>> >>> >>> I'd say its useful to me, if anything because I've learned quite a few >>> things already from this comparison, and I hope to learn more. >>> >>> If Var reification is part of the slowness of Clojure startup over >>> Java's, and ClojureScript managed without it, yet it delivered 90% of the >>> practical benefits of Var reification, I could see a potential here maybe. >>> Something similar to a dynamic or AOT. Flagging some Vars which need not be >>> reified, or compiling to non reified Vars if fast startup time is what the >>> user would rather have. I could see this being desirable for use cases like >>> AWS Lambda, or small scripts, if it had a drastic startup improvement. >>> >>> The concurrency issue is interesting, and would definitely be unique to >>> Clojure over ClojureScript. First time I hear about this being a possible >>> bottleneck for startup time. Are the concurrency checks java's? Or are >>> these higher level Clojure concurrency checks? Is there possible >>> improvement from the Clojure side of them to make them faster? >>> >>> @tbc++ seems to imply the apples to oranges are due to the platforms, >>> and I can accept this to be true, except that I've seen suggestions that >>> the slow startups are due to either Clojure's implementation causing >>> startup bottlenecks, or Clojure's core design preventing any kind of fast >>> startup implementation. Meaning the culprit is Clojure and not the JVM. But >>> as I find myself thinking about ClojureScript, I wonder if this is true. If >>> Clojure's core design is the bottleneck, then why doesn't ClojureScript >>> suffer too? And so, maybe its because it has altered some core design >>> choices, like concurrency and Var reification. Is it just that? Or is there >>> also bottleneck in the current Clojure implementation on the JVM, which >>> were implemented more efficiently on ClojureScript? I know Alex Miller is >>> working on some of those, and every version of Clojure optimizes, but I've >>> also heard nothing here is expected to create a game changer improvement >>> (appart from possibly grouping functions under one class). And if its >>> neither the implementation, or the core design choices, then I have to >>> conclude that it is in fact the JVM's fault, in that its core design is >>> making what Clojure does on startup more expensive then say the V8 design. >>> Which one of those three things (or possible combination is it) is what I'm >>> trying to seek answer for here. >>> >>> Thanks everyone, >>> Didier >>> >>> On Thursday, 25 January 2018 12:53:03 UTC-8, tbc++ wrote: >>>> >>>> Really, any comparisons between JS and JVM startup times are not useful >>>> at all. For a long list of reasons, not limited to: >>>> >>>> * CLJS doesn't have Vars, CLJ does >>>> * JS VMs are highly tuned for excellent startup times >>>> * JVM Bytecode is a binary format expressing classes, JS files are text >>>> files expressing functions and data transformations >>>> * JVM is class based, JS is prototype based >>>> * JVM is multithreaded and designed to handle several GB of data, JS >>>> VMs are single threaded and designed to often deal with less than a GB of >>>> data. >>>> * HotSpot (and most) JVMs are method JITS, JS engines often use many >>>> profiling methods that are closer to that of a tracing JIT >>>> * The JVM performs extensive security analysis on loaded bytecode, JS >>>> engines disallow most security flaws via syntax restrictions >>>> * CLJS supports tree shaking and minifcation. >>>> >>>> All this adds up to an apples-to-oranges comparison. They are >>>> completely different platforms, the numbers between the two won't be close, >>>> and drawing any sort of comparison between the two isn't very useful at >>>> all. >>>> >>>> -- >>>> >>>> * No multithreaded safety in vars is not what takes up most of the >>>> startup time in Clojure. We're talking about single threaded access (var >>>> initing isn't multithreaded) to a primitive that is updated via a CAS. The >>>> highest cost you'll see accessing a var in this situation is somewhere in >>>> the range of a cache miss or two. >>>> >>>> >>>> >>>> On Thu, Jan 25, 2018 at 1:26 PM, Stephen Nelson <ste...@montoux.com> >>>> wrote: >>>> >>>>> The JVM is concurrent whereas Javascript VMs are singled-threaded. Var >>>>> initialisation in Clojure uses concurrency primitives to ensure that >>>>> namespaces are always consistent for all threads, whereas Clojurescript >>>>> simply assigns to variables. Our profiling of Clojure on the JVM indicates >>>>> that a lot of the time spent in namespace initialisation is spent in >>>>> concurrency structures, and this seems much more significant for >>>>> non-clojure-core namespaces. >>>>> >>>>> On Fri, Jan 26, 2018 at 7:22 AM Mikhail Gusarov <dott...@dottedmag.net> >>>>> wrote: >>>>> >>>>>> cljs vars are not reified. >>>>>> >>>>>> On Thu, 25 Jan 2018, at 18:24, Didier wrote: >>>>>> > Based on the profiling performed here >>>>>> > http://clojure-goes-fast.com/blog/clojures-slow-start/ on 1.9, >>>>>> > >>>>>> > It looks like clojure/core__init.load is the slowest bit with load >>>>>> and >>>>>> > requiring spending the most time on, as well as loadClass, followed >>>>>> by >>>>>> > clojure/lang/Var.invoke. >>>>>> > >>>>>> > Wouldn't ClojureScript also need to initialize all Vars and execute >>>>>> top >>>>>> > level forms? You'd think that part would be slower in JavaScript no? >>>>>> > >>>>>> > -- >>>>>> > You received this message because you are subscribed to the Google >>>>>> > Groups "Clojure" group. >>>>>> > To post to this group, send email to clo...@googlegroups.com >>>>>> > Note that posts from new members are moderated - please be patient >>>>>> with >>>>>> > your first post. >>>>>> > To unsubscribe from this group, send email to >>>>>> > clojure+u...@googlegroups.com >>>>>> > For more options, visit this group at >>>>>> > http://groups.google.com/group/clojure?hl=en >>>>>> > --- >>>>>> > You received this message because you are subscribed to the Google >>>>>> > Groups "Clojure" group. >>>>>> > To unsubscribe from this group and stop receiving emails from it, >>>>>> send >>>>>> > an email to clojure+u...@googlegroups.com. >>>>>> > For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "Clojure" group. >>>>>> To post to this group, send email to clo...@googlegroups.com >>>>>> Note that posts from new members are moderated - please be patient >>>>>> with your first post. >>>>>> To unsubscribe from this group, send email to >>>>>> clojure+u...@googlegroups.com >>>>>> For more options, visit this group at >>>>>> http://groups.google.com/group/clojure?hl=en >>>>>> --- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "Clojure" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>> send an email to clojure+u...@googlegroups.com. >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>> >>>>> >>>>> -- >>>>> Stephen Nelson | Platform Lead Developer | Montoux >>>>> e. ste...@montoux.com >>>>> t. @montoux >>>>> w. montoux.com >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To post to this group, send email to clo...@googlegroups.com >>>>> Note that posts from new members are moderated - please be patient >>>>> with your first post. >>>>> To unsubscribe from this group, send email to >>>>> clojure+u...@googlegroups.com >>>>> For more options, visit this group at >>>>> http://groups.google.com/group/clojure?hl=en >>>>> --- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to clojure+u...@googlegroups.com. >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> >>>> >>>> >>>> -- >>>> “One of the main causes of the fall of the Roman Empire was >>>> that–lacking zero–they had no way to indicate successful termination of >>>> their C programs.” >>>> (Robert Firth) >>>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to clojure+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> >> >> -- >> “One of the main causes of the fall of the Roman Empire was that–lacking >> zero–they had no way to indicate successful termination of their C >> programs.” >> (Robert Firth) >> > > > > -- > “One of the main causes of the fall of the Roman Empire was that–lacking > zero–they had no way to indicate successful termination of their C > programs.” > (Robert Firth) > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- Nathan Fisher w: http://junctionbox.ca/ -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.