Emacs 使用regexp为imenu的文件编制索引,性能是不可接受的
我正在为Emacs 使用regexp为imenu的文件编制索引,性能是不可接受的,emacs,elisp,Emacs,Elisp,我正在为imenu create index function生成一个函数,用于索引源代码模块,例如 它可以工作,但提供了完全不可接受的性能。有解决这个问题的建议吗 背景 我看了一下js.el,它是从v23.2开始重新标记的“espresso”,现在包含在emacs中。它很好地索引了Javascript文件,很好地处理了匿名函数和各种常用的编码样式和模式。例如,在javascript中,可以执行以下操作: (function() { var x = ... ; function
imenu create index function
生成一个函数,用于索引源代码模块,例如
它可以工作,但提供了完全不可接受的性能。有解决这个问题的建议吗
背景
我看了一下js.el,它是从v23.2开始重新标记的“espresso”,现在包含在emacs中。它很好地索引了Javascript文件,很好地处理了匿名函数和各种常用的编码样式和模式。例如,在javascript中,可以执行以下操作:
(function() {
var x = ... ;
function foo() {
if (x == 1) ...
}
})();
…定义x
为“私有”或无法从其他代码访问的范围。js.el使用regexps很好地对其进行了索引,它还对该范围内的内部函数(匿名或非匿名)进行了索引。它工作得很快。一个大模块可以在不到一秒钟的时间内建立索引
我试着在csharp模式下采用类似的方法,但它相当复杂。在Js中,所有被索引的东西都是一个函数。因此,起始正则表达式是“函数”,两端都有一些详细说明。一旦发现出现函数
关键字,则有4-8个其他regexp可通过查看
-数量取决于设置。js模式的一个优点是,您可以为各种编码样式打开或关闭regexp,以加快速度。默认的“样式”适用于我尝试的大多数代码
这在csharp模式下不起作用。它可以工作,但是它的性能很差,以至于不能很好地使用。我想原因是
- C#中没有单个标记关键字,因为
在javascript中起作用。在C#中,我需要查找名称空间、类、结构、接口、枚举等function
- csharp构造的定义具有很大的灵活性。例如,类可以定义基类以及实现的接口。另一个例子:方法的返回类型不是一个简单的类似于字符串的单词,而是一些混乱的东西,比如
。索引例程需要处理所有这些情况,并捕获匹配项。这使得它运行缓慢字典
- 我用了很多的
。我在当前方法中使用的标记是开放的花括号。一旦我找到其中一个,我就使用回首往事
来确定卷曲是否是一个类、接口、枚举、方法等。我读到回溯
可能很慢;我不清楚它比看要慢多少回溯
- 一旦我找到一对开合的卷发,我就调用
,以索引里面的内容。不确定这是否会降低性能。我怀疑这不是罪魁祸首,因为我看到的性能问题发生在具有一个名称空间和2或3个类的模块中,这意味着窄带被调用的次数是总数的3或4倍窄到区域
- 避免
。我不知道如何做到这一点,因为当<代码>重新搜索前进>代码>发现,例如关键字<代码>类< /代码>时,光标已经在类声明的中间。代码>回顾似乎至关重要回头看
- 不要使用opencurly作为标记,而是使用诸如enum、interface、namespace和class之类的关键字
- 避免
缩小到区域
回首往事
可能非常缓慢。这是我要做的第一件事。一件非常有用的事情是使用limit
arg,例如,将搜索限制在当前行的开头。另一种方法是,当你点击打开的卷发dobackward char
然后backward sexp
(或其他)到达前一个单词的前面,然后使用查看
使用关键字搜索而不是打开卷发可能是我应该做的。可能类似于(向前搜索“\\(枚举\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
我不知道窄到区域的成本有多高,但如果您找到一个开放的卷发,则可以避免此问题,方法是保存偏移,向前搜索sexp,并保留点作为当前迭代(我假设是递归)搜索的限制