unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* C++-mode indenting performance depends on length of previous function?
@ 2018-06-29 15:20 Jason Rohrer
  2018-06-30 19:47 ` Alan Mackenzie
  0 siblings, 1 reply; 3+ messages in thread
From: Jason Rohrer @ 2018-06-29 15:20 UTC (permalink / raw)
  To: emacs-devel

Tested in Emacs 23, 24, and 25.  Same behavior with or without font-lock-mode, and linum-mode is off.

I have a 6000-line C++ function with a bunch of internal nesting.  I would expect auto-indenting to be a bit slow inside this function, but it turns out that it mostly is not slow, especially inside sub-blocks of the giant function (inside the top-level block, it is a bit slow).

However, I'm seeing enormous slow-down when creating sub-blocks inside the NEXT function, even if it is a short function.  Both functions are top-level blocks with 0-indent, but it seems like the auto-indent and auto-bracket stuff is scanning the previous function for some reason.  And, unlike the good performance inside sub-blocks of the huge function, I'm seeing slow performance in sub-blocks and sub-sub-blocks of the next function.  Nesting doesn't seem to change anything... It must still be scanning the previous function block entirely for some reason.  If I put a tiny dummy function in between, the dummy function is slow to edit, but the next function is fast again.

void longComplicatedFunction() {
    // imagine 6000 lines here
}

void anotherShorterFunction() {
    // very slow to edit this
}



But with the dummy function in between, I see:

void longComplicatedFunction() {
    // imagine 6000 lines here
}

void dummyFunction() {
    // very slow to edit this, now
}

void anotherShorterFunction() {
    // fast editing, back to normal
}


Profiler shows that electric-brace and electric-paren are to blame:

- command-execute                                               18219  99%
 - call-interactively                                           18217  99%
  + c-electric-brace                                            11417  62%
  + c-electric-paren                                             2562  14%
  + c-indent-line-or-region                                      2223  12%
  + newline                                                      1927  10%
  + self-insert-command                                            42   0%
  + minibuffer-complete                                            18   0%
  + execute-extended-command                                        9   0%
  + c-electric-backspace                                            7   0%
  + byte-code                                                       7   0%
  + previous-line                                                   5   0%
+ ...                                                              21   0%
+ redisplay_internal (C function)                                   4   0%
+ timer-event-handler                                               2   0%


The live code in question is here:

https://github.com/jasonrohrer/OneLife/blob/master/gameSource/LivingLifePage.cpp

Grep for "dummyFunctionA" and then try adding some new blocks inside that function. Since it's the function after the gigantic ::step function, editing it is slow. But the next function, ::makeActive, is fast to edit.

Leaving dummyFunctionA in place is my current work-around.  Otherwise, makeActive is simply too slow/frustrating to edit.



(And before you tell me to re-factor the big function, I have my reasons---it's a game loop---and "emacs can't handle it" shouldn't be a driving reason to re-factor.)



Anyone know what's going on here?

Why does the previous top-level block matter?  Why doesn't it stop scanning backward when it hits the beginning of the current top-level block?


Jason



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

* Re: C++-mode indenting performance depends on length of previous function?
  2018-06-29 15:20 C++-mode indenting performance depends on length of previous function? Jason Rohrer
@ 2018-06-30 19:47 ` Alan Mackenzie
  2018-07-01 18:26   ` Jason Rohrer
  0 siblings, 1 reply; 3+ messages in thread
From: Alan Mackenzie @ 2018-06-30 19:47 UTC (permalink / raw)
  To: Jason Rohrer; +Cc: emacs-devel

Hello, Jason.

Thanks for the report.  Thanks even more for making your source file so
easily available, thus making it very easy for me to try things out.

On Fri, Jun 29, 2018 at 08:20:51 -0700, Jason Rohrer wrote:
> Tested in Emacs 23, 24, and 25.  Same behavior with or without
> font-lock-mode, and linum-mode is off.

I think the problem is fixed in Emacs 26.1.  This was released a little
over a month ago.

> I have a 6000-line C++ function with a bunch of internal nesting.  I
> would expect auto-indenting to be a bit slow inside this function, but
> it turns out that it mostly is not slow, especially inside sub-blocks
> of the giant function (inside the top-level block, it is a bit slow).

I did an hg bisection on the CC Mode sources, and the git commit which
seems to have serendipitously fixed the bug is:

   commit 59d07875df9d44568d93a7517853e6a5ccaf1e5b
    Author: Alan Mackenzie <acm@muc.de>
    Date:   Sat Jul 1 15:43:07 2017 +0000

    Make C++ digit separators work.  Amend the handling of single quotes generally

> However, I'm seeing enormous slow-down when creating sub-blocks inside
> the NEXT function, even if it is a short function.  Both functions are
> top-level blocks with 0-indent, but it seems like the auto-indent and
> auto-bracket stuff is scanning the previous function for some reason.
> And, unlike the good performance inside sub-blocks of the huge
> function, I'm seeing slow performance in sub-blocks and sub-sub-blocks
> of the next function.  Nesting doesn't seem to change anything... It
> must still be scanning the previous function block entirely for some
> reason.  If I put a tiny dummy function in between, the dummy function
> is slow to edit, but the next function is fast again.

I saw the slowness too, on Emacs 25.3.  On my machine (which isn't by
any means slow) there were pauses of, perhaps 0.5s when CC Mode had to
indent things, in your tiny "workaround" function.

Again, could you please try out Emacs 26.1

[ .... ]

> The live code in question is here:

> https://github.com/jasonrohrer/OneLife/blob/master/gameSource/LivingLifePage.cpp

:-)

> Grep for "dummyFunctionA" and then try adding some new blocks inside
> that function. Since it's the function after the gigantic ::step
> function, editing it is slow. But the next function, ::makeActive, is
> fast to edit.

> Leaving dummyFunctionA in place is my current work-around.  Otherwise,
> makeActive is simply too slow/frustrating to edit.



> (And before you tell me to re-factor the big function, I have my
> reasons---it's a game loop---and "emacs can't handle it" shouldn't be
> a driving reason to re-factor.)

As maintainer of CC Mode, I've seen far worse (like a 6,000 line long
macro).  :-(

> Anyone know what's going on here?

> Why does the previous top-level block matter?  Why doesn't it stop
> scanning backward when it hits the beginning of the current top-level
> block?

I'm speculating, but sometimes it matters whether or not a brace pair is
at the top level, particularly in such a complicated language as C++.
With a long function this can take a long time to determine.

Yet again, would you please see if you agree with me that the bug has
been fixed in Emacs 26.1.  If there are still unacceptable pauses, I'll
take a more detailed look at the problem.  Thanks!

> Jason

-- 
Alan Mackenzie (Nuremberg, Germany).



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

* Re: C++-mode indenting performance depends on length of previous function?
  2018-06-30 19:47 ` Alan Mackenzie
@ 2018-07-01 18:26   ` Jason Rohrer
  0 siblings, 0 replies; 3+ messages in thread
From: Jason Rohrer @ 2018-07-01 18:26 UTC (permalink / raw)
  To: emacs-devel; +Cc: emacs-devel

Confirmed that it is fixed in 26.1

Thanks!

Jason


On Sat, Jun 30, 2018, at 12:47 PM, Alan Mackenzie wrote:
> Hello, Jason.
> 
> Thanks for the report.  Thanks even more for making your source file so
> easily available, thus making it very easy for me to try things out.
> 
> On Fri, Jun 29, 2018 at 08:20:51 -0700, Jason Rohrer wrote:
> > Tested in Emacs 23, 24, and 25.  Same behavior with or without
> > font-lock-mode, and linum-mode is off.
> 
> I think the problem is fixed in Emacs 26.1.  This was released a little
> over a month ago.
> 
> > I have a 6000-line C++ function with a bunch of internal nesting.  I
> > would expect auto-indenting to be a bit slow inside this function, but
> > it turns out that it mostly is not slow, especially inside sub-blocks
> > of the giant function (inside the top-level block, it is a bit slow).
> 
> I did an hg bisection on the CC Mode sources, and the git commit which
> seems to have serendipitously fixed the bug is:
> 
>    commit 59d07875df9d44568d93a7517853e6a5ccaf1e5b
>     Author: Alan Mackenzie <acm@muc.de>
>     Date:   Sat Jul 1 15:43:07 2017 +0000
> 
>     Make C++ digit separators work.  Amend the handling of single quotes 
> generally
> 
> > However, I'm seeing enormous slow-down when creating sub-blocks inside
> > the NEXT function, even if it is a short function.  Both functions are
> > top-level blocks with 0-indent, but it seems like the auto-indent and
> > auto-bracket stuff is scanning the previous function for some reason.
> > And, unlike the good performance inside sub-blocks of the huge
> > function, I'm seeing slow performance in sub-blocks and sub-sub-blocks
> > of the next function.  Nesting doesn't seem to change anything... It
> > must still be scanning the previous function block entirely for some
> > reason.  If I put a tiny dummy function in between, the dummy function
> > is slow to edit, but the next function is fast again.
> 
> I saw the slowness too, on Emacs 25.3.  On my machine (which isn't by
> any means slow) there were pauses of, perhaps 0.5s when CC Mode had to
> indent things, in your tiny "workaround" function.
> 
> Again, could you please try out Emacs 26.1
> 
> [ .... ]
> 
> > The live code in question is here:
> 
> > https://github.com/jasonrohrer/OneLife/blob/master/gameSource/LivingLifePage.cpp
> 
> :-)
> 
> > Grep for "dummyFunctionA" and then try adding some new blocks inside
> > that function. Since it's the function after the gigantic ::step
> > function, editing it is slow. But the next function, ::makeActive, is
> > fast to edit.
> 
> > Leaving dummyFunctionA in place is my current work-around.  Otherwise,
> > makeActive is simply too slow/frustrating to edit.
> 
> 
> 
> > (And before you tell me to re-factor the big function, I have my
> > reasons---it's a game loop---and "emacs can't handle it" shouldn't be
> > a driving reason to re-factor.)
> 
> As maintainer of CC Mode, I've seen far worse (like a 6,000 line long
> macro).  :-(
> 
> > Anyone know what's going on here?
> 
> > Why does the previous top-level block matter?  Why doesn't it stop
> > scanning backward when it hits the beginning of the current top-level
> > block?
> 
> I'm speculating, but sometimes it matters whether or not a brace pair is
> at the top level, particularly in such a complicated language as C++.
> With a long function this can take a long time to determine.
> 
> Yet again, would you please see if you agree with me that the bug has
> been fixed in Emacs 26.1.  If there are still unacceptable pauses, I'll
> take a more detailed look at the problem.  Thanks!
> 
> > Jason
> 
> -- 
> Alan Mackenzie (Nuremberg, Germany).



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

end of thread, other threads:[~2018-07-01 18:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-29 15:20 C++-mode indenting performance depends on length of previous function? Jason Rohrer
2018-06-30 19:47 ` Alan Mackenzie
2018-07-01 18:26   ` Jason Rohrer

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