From: Dmitry Gutov <dgutov@yandex.ru>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: 15294@debbugs.gnu.org
Subject: bug#15294: 24.3.50; js2-mode parser is several times slower in lexical-binding mode
Date: Sun, 15 Sep 2013 03:11:41 +0300 [thread overview]
Message-ID: <5234FB3D.40209@yandex.ru> (raw)
In-Reply-To: <jwvwqmjld1r.fsf-monnier+emacs@gnu.org>
On 14.09.2013 17:27, Stefan Monnier wrote:
>>> It seems the slowdown is indeed linked to the way `catch' is handled
>>> (indeed, this non-idiomatic ELisp code ends up byte-compiled in a really
>>> poor way).
>> What's non-idiomatic about this use of `catch'?
>
> The non-idiomatic part is the "one big let on top, with lots of setq
> inside". It's clearly C code in Elisp syntax.
Or rather Java code, considering its origins. In general, we have to
stay close enough to the SpiderMonkey codebase to be able to port new
syntax features easily.
You've explained how this is bad when combined with closures, but other
than gotchas with `catch' (and `condition-case', I'm assuming), we don't
have any higher-order functions in the parser. No lambda forms anywhere,
at least.
Can the fact that `dotimes', `dolist' and `loop' are advised with
`cl--wrap-in-nil-block', which expands into `catch' form, make much of a
difference?
>> It does not make much of a difference in the interpreted mode.
>
> The interpreted performance is affected by completely different factors.
> My guess for the interpreted case is that there are simply "too many"
> local variables: the environment is represented by a simple alist, so
> variable lookup time is proportional to the number of local variables.
> That fine when there are 5 local variables, but is inefficient when you
> have 100 (better would be a balanced tree or maybe a hash table).
`js2-get-token' has 13 local variables (*). Which is, while not a
little, far from 100. Most of the other functions have fewer than that.
Are you counting the global variables, too? The dynamic-binding
interpreter has to work with them, too. How is it that much faster?
(*) According to Steve's notes, symbol lookup in alists is faster than
in Emacs hashtables until 50+ elements. Or was, around the year 2009.
> This said, I'm not terribly concerned about it: if you need it to go
> fast, you should byte-compile the code.
I guess so. The sloppy users who disregarded the instructions to
byte-compile the code were actually creating a bad reputation for
js2-mode 1-2 years ago, but since package.el is much more popular now,
it should be less of a problem.
>> But 2.6 vs 2.1, it still a noticeable regression. Do you suppose the usage
>> of `setq' is the main contributor?
>
> The problem goes as follows: ...
Thank you for the detailed explanation.
There are a few `catch' forms left there, for tags `continue' and
`break', used for control flow. So, most of the 0.5s difference left is
likely due to them, right?
I wonder how hard it'll be to rewrite that without `catch'.
>> (*) Would you take a look at it, too? It has quite a few changes in
>> js2-get-token' and related functions.
>
>> They also make performing the same change as in your patch more
>> difficult, since I'm actually using the value returned by `catch'
>> before returning from the function.
>
> That's not a problem. The rule to follow is simply: sink the `let'
> bindings closer to their use. You don't need to `let' bind all those
> vars together in one big `let': you can split this let into various
> `let's which you can then move deeper into the code. In some cases
> you'll find that some of those vars don't even need to be `setq'd any
> more.
Thanks, will do.
next prev parent reply other threads:[~2013-09-15 0:11 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-06 20:59 bug#15294: 24.3.50; js2-mode parser is several times slower in lexical-binding mode Dmitry Gutov
2013-09-06 23:44 ` Xue Fuqiao
2013-09-07 3:15 ` Stefan Monnier
2013-09-08 22:32 ` Stefan Monnier
2013-09-10 2:04 ` Stefan Monnier
2013-09-13 3:40 ` Stefan Monnier
2013-09-13 3:59 ` Drew Adams
2013-09-13 4:37 ` Stefan Monnier
2013-09-13 5:45 ` Drew Adams
2013-09-13 13:01 ` Stefan Monnier
2013-09-14 0:09 ` Lexical let and setq Michael Welsh Duggan
2013-09-14 3:46 ` Stefan Monnier
2013-09-14 11:13 ` Lars Magne Ingebrigtsen
2013-09-14 14:04 ` Pascal J. Bourguignon
2013-09-15 5:11 ` Stefan Monnier
2013-09-14 21:47 ` Richard Stallman
2013-09-15 5:09 ` Stefan Monnier
2013-09-15 16:54 ` Richard Stallman
2013-09-15 17:06 ` Stefan Monnier
2013-09-16 10:47 ` Richard Stallman
2013-09-14 4:20 ` bug#15294: 24.3.50; js2-mode parser is several times slower in lexical-binding mode Dmitry Gutov
2013-09-14 14:27 ` Stefan Monnier
2013-09-15 0:11 ` Dmitry Gutov [this message]
2013-09-15 5:04 ` Stefan Monnier
2013-09-15 16:54 ` Richard Stallman
2013-09-15 0:24 ` Dmitry Gutov
2013-09-15 5:06 ` Stefan Monnier
2013-09-18 23:48 ` Stefan Monnier
2013-09-22 4:56 ` Dmitry Gutov
2013-10-03 5:00 ` Stefan Monnier
2013-10-04 2:38 ` Dmitry Gutov
2013-10-04 13:52 ` Stefan Monnier
2013-10-05 3:27 ` Dmitry Gutov
2014-12-14 12:31 ` Dmitry Gutov
2014-12-14 14:08 ` Stefan Monnier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5234FB3D.40209@yandex.ru \
--to=dgutov@yandex.ru \
--cc=15294@debbugs.gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.