With a few custom patches (which are pending in jira) + AOT + direct 
linking + lazy vars + var meta elision + jvm flags, I have gotten raw 
startup as low as ~450 ms. Past that, radical changes are probably required 
which are unlikely to be worth doing.

On your conclusions:

1. minimize CAS'es - I'm doubtful this would make much difference. Hotspot 
is usually pretty good at optimizing that stuff in single-threaded 
uncontended scenarios. I will wave in the general direction of immutable 
namespaces to a place that I think is an opportunity to improve a range of 
issues like this.

2. Lazy vars effectively do this (in tandem with AOT and direct linking) 
and it can help 20-30% (presuming you have compiled stuff to use). However, 
most startup cases don't have AOT compiled code to work with and thus this 
won't help at all.

3. Prefetching - as you found, I would not expect this to be useful enough 
to be worth the pain and fragility involved.

4. jaotc - I think this *is* likely to be useful for cases where you can 
pre-stage stuff like this, in particular core itself is a perfect 
opportunity. People have already tested this 
(https://mjg123.github.io/2017/10/04/AppCDS-and-Clojure.html) and found it 
useful. But again, requires pre-AOT'ed code.

I don't think most of these changes help at all though in the most common 
case where you are spinning up a project with a lot of non-AOT'ed code - 
the 10s of seconds of read/compile/init times dwarf this stuff. Rich and I 
working on an idea to help with this.

On Thursday, January 25, 2018 at 11:47:32 PM UTC-6, Nathan Fisher wrote:
>
> 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 
> <https://www.google.com/url?q=https%3A%2F%2Fjunctionbox.ca%2F2018%2F01%2F04%2Fclojure-class-prefetching.html&sa=D&sntz=1&usg=AFQjCNGztHxa9E7A5PbzIdoK_5PK_bqzVw>
>
> 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
>  
> <https://www.google.com/url?q=https%3A%2F%2Fjunctionbox.ca%2F2017%2F12%2F26%2Fclojure-startup-walkthrough.html%23conclusions&sa=D&sntz=1&usg=AFQjCNFDrtWr7uhBX8IZYnv576PWYVM_TA>
>
> 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.

Reply via email to