emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

C++-mode indenting performance depends on length of previous function?


From: Jason Rohrer
Subject: C++-mode indenting performance depends on length of previous function?
Date: Fri, 29 Jun 2018 08:20:51 -0700

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]