优化字体锁定性能


13

我想执行锚字体锁定匹配的变体。我有以名称列表开头的函数定义,并且我希望这些名称在函数体内突出显示。

我已经创建了一个执行此操作的函数,并使用jit-lock-register将其注册为jit-lock函数,但是,性能相当差,并且较大文件中的滚动滞后。

  • 如何评估效果?如果我只是在一个大文件上调用函数(前后有浮动时间,或者有elp),那么我得到的性能将发生巨大变化,这需要0.65到12秒的时间。有推荐的基准测试字体锁定性能的方法吗?
  • 在font-lock-keywords中定义的锚定匹配器与通过jit-lock-register添加功能之间在性能上有什么区别吗?

编辑:似乎性能的变化与垃圾回收有关,我的jit-lock函数的调用每次调用都会逐渐变慢,直到运行垃圾回收为止,此时它们又变快了。


对于第一项,请尝试分析器。
马拉巴巴2014年

我也可以(并且已经)使用事件探查器来查看代码中哪些部分需要花费时间,但是由于性能如此不一致,因此很难判断我所做的任何更改是否在改进。
JoakimHårsman2014年

你有一些我们可以测试的代码吗?这可能对我们有很大帮助。
PythonNut

1
尽管与概要分析或微优化无关,但实际上:我发现font-lock-studio软件包是了解字体锁性能的另一个有用工具。它可以像其他交互式步进调试器一样提供帮助-您可能会发现执行路径不是您期望的,这是主要的性能问题。
格雷格·亨德肖特

感谢有关font-lock-studio的提示,它很棒!虽然对jit-lock-functions并没有帮助,但是其他所有功能都可以。
JoakimHårsman'15

Answers:


8

事实证明,性能的巨大变化与垃圾回收有关。直到运行垃圾回收之前,对该函数的每次调用都会变慢。使用股票emacs,gc每隔几秒钟运行一次,但是我在init.el中增加了一行以缩短启动时间,从而将gc-cons-threshold设置为20 MB,这意味着gc很少运行,从而导致基准测试报告时间越来越慢,直到在几分钟后运行gc为止,然后时间会直线下降并再次变快。

恢复为默认的gc-cons-threshhold后,基准测试变得更加容易。

然后,我使用内置的事件探查器(M-x profiler-start)对内存进行了探查,发现对语法pppss的调用引起了最多的分配,因此在进行一些优化以减少对语法pppss的调用后,我获得了可接受的性能。

使用jit-lock-mode(通过jit-lock-register添加功能)似乎是使多行字体锁定可靠工作的最简单方法,因此我选择了这种方法。

编辑:发现非常大的缓冲区中的性能仍然不够好之后,我花了很多时间来优化cpu的使用和分配,并使用内置的Emacs profiler(M-x profiler-start)来衡量性能的提高。但是,在非常大的缓冲区中快速滚动时,Emacs仍会结结巴巴并挂起。删除我注册的jit-lock功能jit-lock-register将消除结结和挂起,但是分析显示jit-lock功能在8毫秒左右完成,这应该足够快速以实现平滑滚动。删除呼叫jit-lock-register并改为使用常规的font-lock-keywords匹配器可以解决此问题。

TLDR:这样做很慢,会结结巴巴:

(defun my-font-lock-function (start end)
"Set faces for font-lock between START and END.")

(jit-lock-register 'my-font-lock-function)

这样做很快,不会结巴:

(defun my-font-lock-function (start end)
"Set faces for font-lock between START and END.")

(defun my-font-lock-matcher (limit)
    (my-font-lock-function (point) limit)
   nil)

(setq font-lock-defaults
  (list 
     ...
    ;; Note that the face specified here doesn't matter since
    ;; my-font-lock-matcher always returns nil and sets the face on
    ;; its own.
    `(my-font-lock-matcher (1 font-lock-keyword-face nil))))

您可以分享您使用的代码吗?您的解决方案可能会帮助寻求实现相同目标的其他人。
曼努埃尔·乌贝蒂

我并没有真正使用任何特定的代码,只是将语法称为ppss。您可以在此处查看有问题的代码:bitbucket.org/harsman/dyalog-mode/src/…寻找dyalog-fontify-locals
JoakimHårsman,2015年

我想dyalog-fontify-locals-matcher应该是my-font-lock-matcher和的一个end应该是limit。无论如何,真的很有趣的发现!
Lindydancer

@Lindydancer:是的,谢谢。固定。
JoakimHårsman'16

1
回复:gc-cons-threshold,如果您纯粹是为了改善启动时间而搞砸内部值,建议您以后使用它emacs-startup-hook来还原它们。
phils
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.