a nitpick on point 1 - I would assume you can't expect hotspot to improve
anything in the timescale of a program startup

am I missing something here?

On Fri, Jan 26, 2018 at 10:32 AM Alex Miller <a...@puredanger.com> wrote:

> 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.
>

-- 
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