GNU bug report logs - #15295
which-func-mode slow in long Python tuple

Previous Next

Package: emacs;

Reported by: Dale <dale <at> codefu.org>

Date: Sat, 7 Sep 2013 00:48:02 UTC

Severity: normal

Done: fgallina <at> gnu.org (Fabián Ezequiel Gallina)

Bug is archived. No further changes may be made.

Full log


Message #11 received at 15295 <at> debbugs.gnu.org (full text, mbox):

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: Alex V. Koval <alex <at> ua2web.com>
Cc: 15295 <at> debbugs.gnu.org
Subject: Re: bug#15295: python mode slow to unusable
Date: Sat, 26 Oct 2013 13:39:21 +0200
Alex V. Koval <alex <at> ua2web.com> writes:

> For me this is happen as well. Emacs, starting from version 24.3 became
> so slow in Python mode that I had to tell all developers at our company
> to use version 24.2 until I sorted this out.
>
> Sit today and started trying various emacs versions, and calling
> different functions. The suggested test case from original author above,
> runs with this benchmark:
>
> (7.3956507 53 1.8788885930000063)

I profiled a bit, and, at least in this example, these two functions
seem to be extremely inefficient in combination:

(defun python-nav-beginning-of-statement ()
  "Move to start of current statement."
  (interactive "^")
  (while (and (or (back-to-indentation) t)
              (not (bobp))
              (when (or
                     (save-excursion
                       (forward-line -1)
                       (python-info-line-ends-backslash-p))
                     (python-syntax-context 'string)
                     (python-syntax-context 'paren))
                (forward-line -1))))
  (point-marker))

(defun python-info-line-ends-backslash-p (&optional line-number)
  "Return non-nil if current line ends with backslash.
With optional argument LINE-NUMBER, check that line instead."
  (save-excursion
    (save-restriction
      (widen)
      (when line-number
        (python-util-goto-line line-number))
      (while (and (not (eobp))
                  (goto-char (line-end-position))
                  (python-syntax-context 'paren)
                  (not (equal (char-before (point)) ?\\)))
        (forward-line 1))
      (when (equal (char-before) ?\\)
        (point-marker)))))

They consume most of the time used.  While the first function goes
backward, the second goes forward to the end in every loop cycle.  This
makes the thing O(n^2), with n being the number of lines of the
expression.

I don't know Python, so I can't make any suggestions.  Who can?  At
least, changing the order of `or' expressions in
`python-nav-beginning-of-statement' seems to help in the example case:

(defun python-nav-beginning-of-statement ()
  "Move to start of current statement."
  (interactive "^")
  (while (and (or (back-to-indentation) t)
              (not (bobp))
              (when (or
                     (python-syntax-context 'string)
                     (python-syntax-context 'paren)
                     (save-excursion
                       (forward-line -1)
                       (python-info-line-ends-backslash-p)))
                (forward-line -1))))
  (point-marker))

It's also not efficient how often `syntax-ppss' is called all the time.


Regards,

Michael.




This bug report was last modified 11 years and 229 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.