我正在为imenu-create-index-function生成一个函数,用于索引源代码模块,用于csharp-mode.el
它工作,但提供完全不能接受的性能。有什么解决办法吗?
背景
我看了一下js.el,它是从v23.2开始就包含在emacs中的“浓缩咖啡”。它很好地索引Javascript文件,使用匿名函数和常用的各种编码样式和模式做得很好。例如,在javascript中可以这样做:
(function() {
var x = ... ;
function foo() {
if (x == 1) ...
}
})();...to定义了一个范围,其中x是“私有”的,或者是其他代码无法访问的。js.el使用regexp很好地对其进行了索引,并且它还对该范围内的内部函数(匿名或非匿名)进行了索引。它工作得很快。一个大模块可以在不到一秒钟的时间内建立索引。
我尝试在csharp中采用类似的方法,但它要复杂得多。在Js中,所有被索引的东西都是一个函数。因此,起始正则表达式是“函数”,并在两端进行了一些详细说明。一旦找到function关键字的出现,就会有4-8个其他regexp通过looking-at进行尝试--数量取决于设置。js模式的一个好处是,您可以为各种编码样式打开或关闭regexp,以加快速度。默认的“样式”适用于我尝试过的大多数代码。
这在夏普模式下行不通。它可以工作,但是性能很差,使得它不能很好地使用。我认为这是因为
function在javascript中的行为。在C#中,我需要查找名称空间、类、结构、接口、枚举等等。Dictionary<String, List<String>>这样混乱的类型。索引例程需要处理所有这些情况,并捕获匹配。这让它的运行充满了血色。looking-back。我在当前方法中使用的标记是开放的大括号。一旦我找到其中一个,我就使用looking-back来确定curly是否是一个类、接口、枚举、方法等等。我读到looking-back可能很慢;我不知道它比looking-at慢多少。narrow-to-region来索引里面的内容。不确定这是否会影响性能。我怀疑这不是主要的罪魁祸首,因为我看到的perf问题发生在一个名称空间和2或3个类的模块中,这意味着窄调用被调用的次数是总数的3或4倍。问题是什么?
我的问题是:您有在C#缓冲区中加速类imenu类索引的任何提示吗?
我在考虑:
looking-back。我不知道如何做到这一点,因为当re-search-forward找到关键字class时,游标已经处于类声明的中间。looking-back似乎是必不可少的。narrow-to-region有什么难听的建议吗?进一步的建议?
我已经尝试过,但我并不热衷于重新访问:为C#构建一个基于智能的解析器,并依赖语义来进行索引。我发现语义很难使用,很难发现,而且有问题。我有一段时间的语义工作,但后来升级到v23.2,它坏了,我再也不能让它工作了。简单的事情--比如索引名称空间关键字--花了很长时间才能解决。我对此很不满意,不想再试一次。
发布于 2011-05-25 20:37:29
我不太懂C#语法,如果不看您的elisp,就很难给出答案,但还是这样。
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来查看找到了哪个关键字。这也可能有助于解决looking-back问题。
我不知道narrow-to-region的开销有多大,但是当您找到一个打开的save-excursion forward-sexp并保留point作为当前迭代(我假设递归)搜索的限制时,就可以避免。
https://stackoverflow.com/questions/6127879
复制相似问题