3

Is there a way to profile or time code that simulates interactive editing?

The gist of what I want to do is that I have some code that runs during font-lock, and sometimes it makes editing sluggish. What I would like is a way to run a test that simulates the editing (and corresponding font-lock operations) and does some timing so I can test which implementations are fastest.

Supposing I have a measure-time macro (eg from https://stackoverflow.com/questions/23622296/emacs-timing-execution-of-function-calls-in-emacs-lisp), this test code would look like this, where example/info.org is the file I want to test on.

(cl-loop for i to 3 collect
     (with-temp-buffer
       (insert-file-contents "example/info.org")
       (org-mode)
       ;; Goto place in file where I know editing becomes slow
       (re-search-forward "ref:")
       (end-of-line)
       (measure-time
        (dotimes (i 5)
          ;; this code should act like if typed a character, triggering a
          ;; font-lock update
          (insert " ")))))

and it would return a list of execution times for the edit operation (in this case inserting characters).

Then, I could try different implementations of the code to see which one makes for the fastest editing.

Are there any standard tools for doing this?

John Kitchin
  • 11,555
  • 1
  • 19
  • 41
  • Are you familiar with `C-h f font-lock-ensure` ? – phils Jun 05 '19 at 04:08
  • I am. Is the idea to put it after the insert command? By default it seems to fontify the entire accessible buffer, which isn't the same as what happens while editing I think. I am not sure how to define the region that should be fontified as the optional arguments for it. If I make it just the current line, then the results seem roughly consistent with the manual typing experience. Any thoughts on how big a lag is noticeable? i.e. is a 0.5 sec delay noticeable while typing? – John Kitchin Jun 05 '19 at 11:14
  • I don't know my way around font-lock, but it looks to me as if `C-h v after-change-functions` is determining when things happen, and the associated start and end points. (That's probably more useful/relevant than `font-lock-ensure`.) – phils Jun 05 '19 at 11:41

1 Answers1

3

You can use the package font-lock-profiler. For each font-lock rule, it measures execution time and the number of times the rule matched.

The package supports measuring time for highlighting a buffer or a region. It also allows measuring time during an editing session. Simply run font-lock-profiler-start, edit your text, and run font-lock-profiles-stop-and-report. Time is initially presented in percent, pressing % converts it to seconds.

Another package that might be of interest is highlight-refontification. When enabled, it paints the background in different colors to represent the region which font-lock rehighlights when the buffer is edited. In most cases, this is only the line in which the edit took place. However, for more advanced modes, this could consist of multiple lines. This is useful to ensure that the region stays within a resonable size.

Of course, for general purpose font-lock development you can use the interactive font-lock debugger font-lock-studio.

Lindydancer
  • 6,095
  • 1
  • 13
  • 25
  • Thanks for these suggestions. I have used the font-lock-profiler and font-lock-studio. I am looking for a non-interactive test though so I can run tests on several different files. The highlight-refontification package is nice, it helped confirm what region I need to focus on, which in my case is just the current line. – John Kitchin Jun 05 '19 at 11:18
  • 1
    @JohnKitchin, you can use font-lock-profiler non-interactively. For example, to check how long it takes to highlight an entire file, enable it using `(font-lock-profiler-instrument-keyword-list font-lock-keywords)`, call something like `(font-lock-fontify-region (point-min) (point-max))`, and inspect the result in `font-lock-profiler-log`. – Lindydancer Jun 05 '19 at 11:46