ankurdave / color-identifiers-mode

Emacs minor mode to highlight each source code identifier uniquely based on its name
308 stars 23 forks source link

color-identifiers-mode is very slow when hideshowvis is enabled #83

Closed eyal0 closed 1 year ago

eyal0 commented 3 years ago

I can't tell which one is the issue here.

When both hideshowvis and color-identifiers-mode are in use, color-identifiers:refresh becomes very slow on large files. When hideshowvis is not loaded, color-identifiers:refresh is much faster (like .5 seconds versus 15 seconds).

To reproduce this, first get hideshowvis installed. Save this file into ~/emacs.d/lisp.

In init.el add

(use-package hideshowvis
  :diminish
  :load-path "~/.emacs.d/lisp"
  :bind ("M-[" . hs-toggle-hiding)
  :init (progn
          (add-hook #'prog-mode-hook (lambda () (hideshowvis-enable) (hideshowvis-symbols)))))

That will cause hideshowvis to open when a programming file is opened, like c++.

Now we need to open a large c++ file. Download this file to ~/Downloads/inference_context.cc.

Now open that file in emacs. Confirm that there are little minus signs in the fringe which can be clicked to shrink and expand code.

Now type M-x color-identifiers:refresh. It should return in under 0.5 seconds.

Now hold page down on the keyboard until you reach the end of the file. Once again, type M-x color-identifiers:refresh. It will take noticeably longer, like 4 seconds or so. This will be the case from now on. Now page up all the way to the top and try again. Now it might be even longer, like 12 seconds.

M-x profiler-start before the slowness and then M-x profiler-report after the slowness shows 99% of the cpu time in thing-at-point, called by symbol-at-point in color-identifiers. It's not clear if that is many more calls to thing-at-point or just more time spent inside the function. I don't know a method to count calls in elisp.

Hi-Angel commented 1 year ago

Can't seem to reproduce.

However, your description sounds like something I've been having before (and without hideshowvis) and I've been trying to reproduce it for the last ½-year or so, it just stopped happening to me.

I have a patch which presumably should alleviate this problem. It doesn't speed up the color-identifiers:refresh per se, so if you run it manually, it should still take just as long to return. However, it should fix the interactivity problem, i.e. the slowness when you can't do anything in the buffer until scan finishes.

Patch is here: patch.zip (github doesn't allow a .patch file, so had to zip it).

It's really just a one-line change, you can do it manually to your color-identifiers-mode.el file, then M-x byte-compile-file it, then restart Emacs. Please test if that helps.

--- a/color-identifiers-mode.el
+++ b/color-identifiers-mode.el
@@ -206,7 +206,7 @@ For cc-mode support within color-identifiers-mode."
     (save-excursion
       (goto-char (point-min))
       (let ((next-change (next-property-change (point))))
-        (while next-change
+        (while (and next-change (not (input-pending-p)))
           (goto-char next-change)
           (let ((face-at-point (get-text-property (point) 'face)))
             (when (or (and face-at-point (memq face-at-point identifier-faces))
eyal0 commented 1 year ago

Weird, I'm not seeing it now either. I'll remember this tip and then next time that I can reproduce the slowness, I will try this.

Hi-Angel commented 1 year ago

So, latest master has undergone quite a lot of optimizations and cleanups. And given this problem is no longer reproducible, I'm inclined to close the report.

Please feel free to reopen if you find a way to reproduce it.

eyal0 commented 5 months ago

I found the issue: https://github.com/sheijk/hideshowvis/issues/11 It is a hideshowvis problem, not color identifiers problem.