首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用regexp为imenu索引文件,性能是不可接受的。

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

Stack Overflow用户
提问于 2011-05-25 16:40:07
回答 1查看 177关注 0票数 1

我正在为imenu-create-index-function生成一个函数,用于索引源代码模块,用于csharp-mode.el

它工作,但提供完全不能接受的性能。有什么解决办法吗?

背景

我看了一下js.el,它是从v23.2开始就包含在emacs中的“浓缩咖啡”。它很好地索引Javascript文件,使用匿名函数和常用的各种编码样式和模式做得很好。例如,在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,以加快速度。默认的“样式”适用于我尝试过的大多数代码。

这在夏普模式下行不通。它可以工作,但是性能很差,使得它不能很好地使用。我认为这是因为

  • C#中没有单独的标记关键字,因为function在javascript中的行为。在C#中,我需要查找名称空间、类、结构、接口、枚举等等。
  • 有很大的灵活性可以用csharp构造来定义。例如,类可以定义基类以及实现的接口。另一个例子:方法的返回类型不是简单的类似单词的字符串,而是像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,它坏了,我再也不能让它工作了。简单的事情--比如索引名称空间关键字--花了很长时间才能解决。我对此很不满意,不想再试一次。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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作为当前迭代(我假设递归)搜索的限制时,就可以避免。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6127879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档