unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Lexical binding: why?
@ 2019-05-28 10:08 Alan Mackenzie
  2019-05-28 12:01 ` Tadeus Prastowo
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Alan Mackenzie @ 2019-05-28 10:08 UTC (permalink / raw)
  To: emacs-devel

Hello, Emacs.

What is the purpose of converting Lisp files to use lexical binding?

I always thought the idea was to speed the SW up.  However, when I tried
converting CC Mode to lexical binding, I got the following timings for
two of my personal benchmarks:

                  Dynamic binding             Lexical binding

Benchmark 1           7.249s                      7.423s 

Benchmark 2          16.743s                     16.691s

.  I thus see no speedup from the use of lexical binding.

Have I, perhaps, made some mistake somewhere?  Does anybody else see
significant speed increases through the use of lexical binding?

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 10:08 Lexical binding: why? Alan Mackenzie
@ 2019-05-28 12:01 ` Tadeus Prastowo
  2019-05-28 12:26 ` Stefan Monnier
  2019-05-28 15:19 ` John Wiegley
  2 siblings, 0 replies; 11+ messages in thread
From: Tadeus Prastowo @ 2019-05-28 12:01 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

Hi Alan,

On Tue, May 28, 2019 at 12:53 PM Alan Mackenzie <acm@muc.de> wrote:
>
> Hello, Emacs.
>
> What is the purpose of converting Lisp files to use lexical binding?

AFAIK, the primary objective is to allow a multi-threaded Emacs.

> I always thought the idea was to speed the SW up.  However, when I tried
> converting CC Mode to lexical binding, I got the following timings for
> two of my personal benchmarks:
>
>                   Dynamic binding             Lexical binding
>
> Benchmark 1           7.249s                      7.423s
>
> Benchmark 2          16.743s                     16.691s
>
> .  I thus see no speedup from the use of lexical binding.

Perhaps it is because a multi-threaded Emacs has not arrived yet?

> Have I, perhaps, made some mistake somewhere?  Does anybody else see
> significant speed increases through the use of lexical binding?
>
> --
> Alan Mackenzie (Nuremberg, Germany).

-- 
Best regards,
Tadeus



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 10:08 Lexical binding: why? Alan Mackenzie
  2019-05-28 12:01 ` Tadeus Prastowo
@ 2019-05-28 12:26 ` Stefan Monnier
  2019-05-28 13:02   ` Dmitry Gutov
  2019-05-28 13:44   ` Alan Mackenzie
  2019-05-28 15:19 ` John Wiegley
  2 siblings, 2 replies; 11+ messages in thread
From: Stefan Monnier @ 2019-05-28 12:26 UTC (permalink / raw)
  To: emacs-devel

> What is the purpose of converting Lisp files to use lexical binding?

The lexical-binding version of Elisp offers closures and avoidance of
corner-case name clashes with higher-order functions.
For this reason, we added it and we're very unlikely to remove it.

In contrast the non-lexical-binding version of Elisp is now
redundant/obsolete because it does not offer any feature not already
available in the lexical-binding mode.  So we only keep it for backward
compatibility and will likely remove it in some distant future.

> I always thought the idea was to speed the SW up.

Not really, no.  It does offer a better potential for optimization, but
nobody has made any effort to take advantage of it so far.

> I thus see no speedup from the use of lexical binding.

That corresponds to my experience as well.  When I installed the
lexical-binding code, my main concern was to not impact existing code,
so the fact that the new lexical-binding mode was "about as fast" was
kind of a happy accident.

> Have I, perhaps, made some mistake somewhere?  Does anybody else see
> significant speed increases through the use of lexical binding?

IIRC some operation in the js2 code was significantly slowed down (in
Emacs-24) by lexical-binding and then (less significantly but still
significantly) sped up when the new condition-case byte-codes were
introduced in 24.4 (and used by default since Emacs-25), so there are
some cases, but by and large I wouldn't expect any major change.


        Stefan




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 12:26 ` Stefan Monnier
@ 2019-05-28 13:02   ` Dmitry Gutov
  2019-05-28 13:25     ` Stefan Monnier
  2019-05-28 13:44   ` Alan Mackenzie
  1 sibling, 1 reply; 11+ messages in thread
From: Dmitry Gutov @ 2019-05-28 13:02 UTC (permalink / raw)
  To: Stefan Monnier, emacs-devel

On 28.05.2019 15:26, Stefan Monnier wrote:
> IIRC some operation in the js2 code was significantly slowed down (in
> Emacs-24) by lexical-binding and then (less significantly but still
> significantly) sped up when the new condition-case byte-codes were
> introduced in 24.4 (and used by default since Emacs-25), so there are
> some cases, but by and large I wouldn't expect any major change.

I think js2-mode in lexical-binding is still ~10% slower than the 
dynamic binding mode, but we switched over anyway because of the sounder 
scoping model and better compiler diagnostics.



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 13:02   ` Dmitry Gutov
@ 2019-05-28 13:25     ` Stefan Monnier
  2019-05-28 13:46       ` Dmitry Gutov
  0 siblings, 1 reply; 11+ messages in thread
From: Stefan Monnier @ 2019-05-28 13:25 UTC (permalink / raw)
  To: emacs-devel

> I think js2-mode in lexical-binding is still ~10% slower than the dynamic
> binding mode,

Oh, well!  I thought we had a better story there :-(

Maybe the speed up I remember was linked to the rework I suggested back
then to work around the poor lexical-scoping performance (mainly moving
a condition-case outside of a loop, IIRC) and that actually improved
performance with both lexical and dynamic binding?


        Stefan




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 12:26 ` Stefan Monnier
  2019-05-28 13:02   ` Dmitry Gutov
@ 2019-05-28 13:44   ` Alan Mackenzie
  2019-05-28 17:21     ` Stefan Monnier
  1 sibling, 1 reply; 11+ messages in thread
From: Alan Mackenzie @ 2019-05-28 13:44 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Hello, Stefan.

On Tue, May 28, 2019 at 08:26:16 -0400, Stefan Monnier wrote:
> > What is the purpose of converting Lisp files to use lexical binding?

> The lexical-binding version of Elisp offers closures and avoidance of
> corner-case name clashes with higher-order functions.
> For this reason, we added it and we're very unlikely to remove it.

Perish the thought!  :-)

> In contrast the non-lexical-binding version of Elisp is now
> redundant/obsolete because it does not offer any feature not already
> available in the lexical-binding mode.  So we only keep it for backward
> compatibility and will likely remove it in some distant future.

> > I always thought the idea was to speed the SW up.

> Not really, no.  It does offer a better potential for optimization, but
> nobody has made any effort to take advantage of it so far.

> > I thus see no speedup from the use of lexical binding.

> That corresponds to my experience as well.  When I installed the
> lexical-binding code, my main concern was to not impact existing code,
> so the fact that the new lexical-binding mode was "about as fast" was
> kind of a happy accident.

> > Have I, perhaps, made some mistake somewhere?  Does anybody else see
> > significant speed increases through the use of lexical binding?

> IIRC some operation in the js2 code was significantly slowed down (in
> Emacs-24) by lexical-binding and then (less significantly but still
> significantly) sped up when the new condition-case byte-codes were
> introduced in 24.4 (and used by default since Emacs-25), so there are
> some cases, but by and large I wouldn't expect any major change.

OK, thanks for the illucidation.

Just in passing, the Elisp manual doesn't seem to be as helpful as it
might be, here.  It doesn't positively recommend using lexical binding
in new programs, for example.

Just in passing2, it seems to be difficult to enable lexical binding
conditionally.  The best that I can come up with is something like:

-*- eval: (setq lexical-binding (> emacs-major-version 25)) -*-

, but that has the irritating consequence of querying the user with "Are
you sure?" for each such file that gets loaded, even though
lexical-binding is a "safe" variable.

>         Stefan

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 13:25     ` Stefan Monnier
@ 2019-05-28 13:46       ` Dmitry Gutov
  0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Gutov @ 2019-05-28 13:46 UTC (permalink / raw)
  To: Stefan Monnier, emacs-devel

On 28.05.2019 16:25, Stefan Monnier wrote:
> Maybe the speed up I remember was linked to the rework I suggested back
> then to work around the poor lexical-scoping performance (mainly moving
> a condition-case outside of a loop, IIRC) and that actually improved
> performance with both lexical and dynamic binding?

No, you remembered correctly: without the new byte-code, the situation 
was noticeably worse. Though maybe it was a 'throw' inside a loop with 
'catch' outside it.

The 10% figure I just got from this thread: 
https://github.com/mooz/js2-mode/issues/524#issuecomment-483010120

But it's actually comparing against an older js2-mode version, not 
against the current code in dynamic-binding mode. I don't have time to 
redo the measurements now myself, but thinking back, maybe the result of 
the byte-code introduction was that lexical-binding became slightly 
faster than dynamic, though not by much.



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 10:08 Lexical binding: why? Alan Mackenzie
  2019-05-28 12:01 ` Tadeus Prastowo
  2019-05-28 12:26 ` Stefan Monnier
@ 2019-05-28 15:19 ` John Wiegley
  2 siblings, 0 replies; 11+ messages in thread
From: John Wiegley @ 2019-05-28 15:19 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

>>>>> "AM" == Alan Mackenzie <acm@muc.de> writes:

AM> I always thought the idea was to speed the SW up.

Note that when I did performance benchmarking of the byte-code intrepreter, by
far the slowest (and most frequent) operation was looking up dynamic
variables. I have the sense that are many sexy optimizations we could do in
this area, though I believe that work has not begun yet.

-- 
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 13:44   ` Alan Mackenzie
@ 2019-05-28 17:21     ` Stefan Monnier
  2019-05-28 17:41       ` Alan Mackenzie
  0 siblings, 1 reply; 11+ messages in thread
From: Stefan Monnier @ 2019-05-28 17:21 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

> Just in passing, the Elisp manual doesn't seem to be as helpful as it
> might be, here.  It doesn't positively recommend using lexical binding
> in new programs, for example.

Thanks for the heads up.

> Just in passing2, it seems to be difficult to enable lexical binding
> conditionally.  The best that I can come up with is something like:
>
> -*- eval: (setq lexical-binding (> emacs-major-version 25)) -*-

Hmm... why do you need that?  Is that because of a performance problem
in Emacs-24's lexical-binding support (likely the one that affects
condition-case and friends)?


        Stefan




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 17:21     ` Stefan Monnier
@ 2019-05-28 17:41       ` Alan Mackenzie
  2019-05-28 17:58         ` Stefan Monnier
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Mackenzie @ 2019-05-28 17:41 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Hello, Stefan.

On Tue, May 28, 2019 at 13:21:22 -0400, Stefan Monnier wrote:
> > Just in passing2, it seems to be difficult to enable lexical binding
> > conditionally.  The best that I can come up with is something like:

> > -*- eval: (setq lexical-binding (> emacs-major-version 25)) -*-

> Hmm... why do you need that?  Is that because of a performance problem
> in Emacs-24's lexical-binding support (likely the one that affects
> condition-case and friends)?

I was thinking more of a bug, since fixed, in older versions of the
lexical-binding code.  Purely hypothetically at the moment, of course.
But this code is surely not so simple that bugs can be ruled out.

But performance problems in older versions of l-b would also be a reason.

For consistency with other features, which can all be enabled
conditionally, surely lexical-binding should also be conditionally
enablable in a reasonable way.

>         Stefan

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Lexical binding: why?
  2019-05-28 17:41       ` Alan Mackenzie
@ 2019-05-28 17:58         ` Stefan Monnier
  0 siblings, 0 replies; 11+ messages in thread
From: Stefan Monnier @ 2019-05-28 17:58 UTC (permalink / raw)
  To: emacs-devel

> I was thinking more of a bug, since fixed, in older versions of the
> lexical-binding code.  Purely hypothetically at the moment, of course.
> But this code is surely not so simple that bugs can be ruled out.

Oh, so it's a hypothetical need.

> For consistency with other features, which can all be enabled
> conditionally, surely lexical-binding should also be conditionally
> enablable in a reasonable way.

Based on the 7 years of experience since Emacs-24.1 was released,
I think YAGNI is a good reason not to bother trying to implement it.

Especially since: if the file's content really does work when
lexical-binding is nil, then a simple workaround for the lack of this
feature is to keep using lexical-binding=nil until the problematic
version(s) are not supported any more and you can set
lexical-binding=t unconditionally.

While I do hope we'll be able to drop support for lexical-binding=nil in
some distant future, "distant" is an import characterization.  I'd be
amazed if this happened before 2030.


        Stefan




^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-05-28 17:58 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-28 10:08 Lexical binding: why? Alan Mackenzie
2019-05-28 12:01 ` Tadeus Prastowo
2019-05-28 12:26 ` Stefan Monnier
2019-05-28 13:02   ` Dmitry Gutov
2019-05-28 13:25     ` Stefan Monnier
2019-05-28 13:46       ` Dmitry Gutov
2019-05-28 13:44   ` Alan Mackenzie
2019-05-28 17:21     ` Stefan Monnier
2019-05-28 17:41       ` Alan Mackenzie
2019-05-28 17:58         ` Stefan Monnier
2019-05-28 15:19 ` John Wiegley

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).