2011-09-01 77 views
2

我有一些从文本中删除HTML标记的代码。我不关心内容(脚本,CSS,文本等),重要的是,至少目前来说,标签本身已被剥离。在C#中优化HTML标记删除

这可能正在进入微型优化剧院,但是这个代码是少数几个会经常针对大量数据运行的函数之一,所以任何百分比保存都可能会从整体应用程序的角度。

目前的代码看起来是这样的:

public static string StripTags(string html) 
{ 
    var currentIndex = 0; 
    var insideTag = false; 
    var output = new char[html.Length]; 

    for (int i = 0; i < html.Length; i++) 
    { 
     var c = html[i]; 
     if (c == '>') 
     { 
      insideTag = false; 
      continue; 
     } 
     if (!insideTag) 
     { 
      if (c == '<') 
      { 
       insideTag = true; 
       continue; 
      } 
      output[currentIndex] = c; 
      currentIndex++; 
     } 
    } 
    return new string(output, 0, currentIndex); 
} 

是否有任何明显的.NET技巧,我错过了这里?有关信息,请使用.net 4.

非常感谢。

+0

那么CDATA部分呢? –

+0

@Dour高拱 - 好问题 - 目前我让这些消亡,因为这符合我解析的数据。 – Timbo

+0

如果代码经常运行,你可能会得到一个很大的加速,只分配你的输出数组一次(显然有一些明智的大小;如果内存是一个问题,你可以使用弱引用)并尽可能地使用它。 java中的一个非常类似的问题得到了大约15%的提速 – Voo

回答

2

在这段代码中,你通过一个字符复制一个。只需检查当前部分(html内部或外部)的结束位置,然后使用Array.copy一次移动整个块,就可以显着加快速度,这将启用较低级别的优化。 (例如在64位上它可以在一个处理器周期中复制4个Unicode字符(4 * 2 * 8位))。标签之间的文本位数可能相当大,因此可能会加起来。

此外,stringbuilder文档提到某处,因为它是在框架中实现的,而不是在C#中它具有无法在托管C#中复制的性能。不知道你怎么可以追加一块你可能会看到的。

问候格特 - 扬

+0

谢谢你,这是一个非常聪明的建议,我将有一个戏剧,并会更新! – Timbo

+0

你完全正确!在每个“块”上执行CopyTo的算法改变了大约15%的速度,这对于函数的每个元素所需的时间而言都是非常令人印象深刻的,足以产生变化。谢谢! – Timbo

+0

你非常欢迎,我喜欢微型优化这种东西8-)。另一个相对简单的优化是在一个任务(线程)上进行搜索并在另一个上进行复制。因为你没有改变读数组。字符串应该足够大以保持它们分开(所以不要错误分享)。 – gjvdkamp

-2

谷歌搜索remove html from string产生该说说使用正则表达式的所有类似下面的许多环节:

public string Strip(string text) 
{ 
    return Regex.Replace(text, @”<(.|\n)*?>”, string.Empty); 
} 
+0

但是,Regex并没有解析html。 – Martin

+0

正则表达式将会非常慢。基准测试,你会很清楚地看到原来的解决方案将会更快。 –

0

,因为它似乎是在.NET中使用HTML文件进行交互的最佳方式你应该看看下面的库:http://htmlagilitypack.codeplex.com/

+0

原始海报只是想剥离HTML标签。他不需要以任何复杂的方式操纵HTML。 HTML敏捷包会为他不需要做的事情增加大量的开销。 –

+0

AgilityPack中的HtmlToText类怎么样?我认为这是删除标签。 – Martin

+0

@Martin - 谢谢,如果我在看更多“聪明”的标签操作,我肯定会考虑AgilityPack。不过,在这种情况下,我只是在寻求速度优化。 – Timbo

0

不解决不存在的问题。

这种方法被调用多少次?许多!多少?几千?不足以保证优化。

你可以做一个Parallel.For,并根据机器加速3-5倍吗?有可能。

您的代码是否依赖于其他许多代码?当然。

有没有可能是你有这样的:

// Some slow code 
StripTags(s); // Super fast version 
// Some more slow code here 

将它无论再怎么快你StripTags?

你从文件中获取它们吗?你从网络上获得它们吗?很少有瓶颈是您的原始CPU能力。

让我重复一遍:

不解决不存在的问题!

+0

我感谢你的关注 - 因此我对自己的微观优化发表了评论。在答案 - 它会每天运行数百万次,超过一些可能延伸到100几Kb的HTML。 TBH我可以接受上述职能的表现,但与社区一起探索替代方案很有意思。例如@gjvdkamp提供了一个我不会考虑的答案...... – Timbo

+0

@Boris非常真实,大多数优化是人们优化某些执行很少次的事情的完全浪费。但是当你等待几个小时来完成一些计算的8路盒子时,请相信我这些黑客使得所有的区别变得非常重要! – gjvdkamp