使用regexp为imenu索引文件,性能是不可接受的

问题描述

|| 我正在为sha0ѭ生成一个函数,以为csharp-mode.el索引源代码模块 它可以工作,但是却提供了完全不可接受的性能。有解决此问题的技巧吗? 的背景 我查看了js.el,这是从v23.2开始包含在emacs中的经过重新标记的“ espresso”。它很好地索引了Javascript文件,并很好地处理了匿名函数以及各种常用的编码样式和模式。例如,在javascript中可以执行以下操作:
(function() {
    var x = ... ; 
    function foo() {
       if (x == 1) ...
    }
})();
...定义一个范围,其中
x
是\“ private \”或无法从其他代码访问。 js.el使用正则表达式对它进行了很好的索引,并且还对该范围内的内部函数(无论是否匿名)进行了索引。它运作迅速。一个大模块可以在不到一秒钟的时间内建立索引。 我尝试在csharp-mode中遵循类似的方法,但是要复杂得多。在Js中,所有被索引的都是函数。因此,开始的正则表达式是\“ function \”,两端都有详细说明。一旦发现出现
function
关键字,则通过
looking-at
会尝试其他4-8个正则表达式-该数目取决于设置。关于js模式的一件好事是,您可以为各种编码样式打开或关闭正则表达式,以加快执行速度。默认的“样式”适用于我尝试的大多数代码。 这在csharp模式下不起作用。它可以工作,但是性能很差,无法使用。我认为原因是 C#中没有单个标记关键字,因为
function
在javascript中表现良好。在C#中,我需要查找名称空间,类,结构,接口,枚举等。 定义csharp构造有很大的灵活性。作为一个示例,一个类可以定义基类以及已实现的接口。另一个例子:方法的返回类型不是一个像单词一样简单的字符串,而可能像
Dictionary<String,List<String>>
那样混乱。索引例程需要处理所有这些情况,并捕获匹配项。这使得它运行得很慢。 我用了很多七英镑。我在当前方法中使用的标记是大括号。一旦找到其中之一,便使用
looking-back
来确定curl是否是类,接口,枚举,方法等。我不清楚它比4英镑慢多少。 一旦找到一对开闭的冰壶,我就叫ѭ11,以索引里面的东西。不知道这是否会降低性能。我怀疑这不是主要的罪魁祸首,因为我看到的性能问题发生在具有一个名称空间和2或3个类的模块中,这意味着狭窄的总数被称为3或4倍。 问题是什么? 我的问题是:您是否有一些技巧来加快C#缓冲区中类似imenu的索引编制? 我正在考虑: 避免
looking-back
。我不确切地知道该怎么做,因为当
re-search-forward
找到关键字
class
时,光标已经在类声明的中间了。
looking-back
似乎很重要。 而不是使用open-curly作为标记,而使用诸如enum,interface,namespace,class之类的关键字 避免
narrow-to-region
有什么好建议吗?进一步的建议? 我尝试过的一些事情,但我并不真正热衷于重新访问:为C#构建一个基于wisent的解析器,并依靠语义进行索引。我发现语义非常难以使用,难以发现且存在问题。我在语义上工作了一段时间,但后来升级到v23.2,但它崩溃了,我再也无法使其正常工作了。简单的事情-例如为命名空间关键字编制索引-需要花费很长时间解决。我对此非常不满意,也不想重试。     

解决方法

我不是很了解C#语法,而且不看您的书本就很难给出答案,但是无论如何,这还是可行的。
looking-back
可能非常慢。这是我要尝试的第一件事。有用的一件事是使用
limit
arg,例如,将搜索限制在当前行的开头。另一种方法是,当您按打开的卷曲时,先按
backward-char
,然后按
backward-sexp
(或其他任何方式)到达上一个单词的开头,然后使用
looking-at
。 使用关键字搜索而不是打开卷曲可能是我会做的。也许像
(re-search-forward \"\\\\(enum\\\\|interface\\\\|namespace\\\\|class\\\\)[ \\t\\n]*{\" nil t)
,然后在第一个捕获组上使用
match-string-no-properties
来查看找到了哪个关键字。这也可能有助于解决“ 7”问题。 我不知道ѭ11expensive有多昂贵,但是当您找到一个开放的curly26
forward-sexp
并保留
point
作为您(我假设是递归)搜索的当前迭代的限制时,可以避免这种情况。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...