Also what I was referencing in terms of the CAS was deferring submission
until the namespace is fully initialised. Something akin to a SQL
transaction where it could use mutable state and then transform it to the
immutable map at commit (eg end of the file). Until a ns fully parsed and
processed (by a single thread) there wouldn’t be any need for the
intermediate data structure to be thread-safe. Kind of like Guava data
structures but for Namespaces.
On Fri, 26 Jan 2018 at 16:57, Nathan Fisher <nfis...@junctionbox.ca> wrote:

> Hi Alex,
>
> That’s cool!
>
> I was looking to explore alternatives optimisations to what you had
> already outlined and which I could potentially do with little effort. I
> started writing something to do parallel loads back in Sept/Oct. and was
> replicating some of what Buck/Blaze/Basel do in terms of a DAG. I wanted
> “pristine” Clojure VMs for each node in the dependency graph but startup
> time was an issue and I couldn’t see an easy way to bring it down.
>
> For point one I was noticing some amount of non-trivial latency in Var
> interning and RT map. Agree Java CAS performance won’t be the issue but (I
> think) there’s something in Clojure that I’m working to improve my
> understanding. For the map I noticed once I eliminated class loading via
> prefetching the map initialisation in RT was a non-trivial amount of time
> (double digit ms). Not something that I think needs prioritisation by any
> means but just a “huh wonder why that is?”.
>
> Justin in terms of Java it’s not a matter of JIT or anything like that.
> It’ll be relatively efficient out of the box, it’s a handful of cpu
> instructions to execute and is around 20 CPU cycles per try (eg
> nanoseconds). It should succeed on or about the first time within the
> context of Clojure startup. An atomic load side depends on how far up the
> memory chain it has to go but shouldn’t be “too expensive” either, more
> expensive than a local variable for sure but not enough to worry about in
> most cases.
>
> Cheers,
> Nathan
> On Fri, 26 Jan 2018 at 15:38, Justin Smith <noisesm...@gmail.com> wrote:
>
>> 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.
>>
> --
> - sent from my mobile
>
-- 
- sent from my mobile

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