【发布时间】:2016-05-08 08:57:07
【问题描述】:
我在c#中写了一个自定义扩展方法,是对扩展方法string[] getBetweenAll(string source, string startstring, string endstring);的改进
原来这个扩展方法找到了两个字符串之间的所有子字符串,例如:
string source = "<1><2><3><4>";
source.getBetweenAll("<", ">");
//output: string[] {"1", "2", "3", "4"}
但是如果你在开始的时候又出现了一个
string source = "<<1><2><3><4>";
source.getBetweenAll("<", ">");
//output: string[] {"<1><2><3><4"}
所以我重写了它以更准确并从“>”向后搜索以找到“
现在我让它工作了,但这里的问题是它太慢了,因为搜索方法每次出现都会跳过整个字符串的每个字符。你知道我怎样才能提高这个功能的速度吗?还是不可能?
这是目前为止的全部代码http://pastebin.com/JEZmyfSG 我在代码需要提高速度的地方添加了 cmets
public static List<int> IndexOfAll(this string main, string searchString)
{
List<int> ret = new List<int>();
int len = searchString.Length;
int start = -len;
while (true)
{
start = main.IndexOf(searchString, start + len);
if (start == -1)
{
break;
}
else
{
ret.Add(start);
}
}
return ret;
}
public static string[] getBetweenAll(this string main, string strstart, string strend, bool preserve = false)
{
List<string> results = new List<string>();
List<int> ends = main.IndexOfAll(strend);
foreach (int end in ends)
{
int start = main.previousIndexOf(strstart, end); //This is where it has to search the whole source string every time
results.Add(main.Substring(start, end - start) + (preserve ? strend : string.Empty));
}
return results.ToArray();
}
//This is the slow function (depends on main.Length)
public static int previousIndexOf(this string main, string find, int offset)
{
int wtf = main.Length ;
int x = main.LastIndexOf(find, wtf);
while (x > offset)
{
x = main.LastIndexOf(find, wtf);
wtf -= 1;
}
return x;
}
我想另一种方法是 PreviousIndexOf(string, int searchfrom);会提高速度.. 像 IndexOf() 一样,除了向后和提供的起始偏移量
【问题讨论】:
-
是的,但很有趣!
-
是否可以使用已编译的正则表达式(例如
<([^>]*)>)来加快速度? -
什么对你来说很慢,你期望什么结果是好的?
-
这里的微优化!您可以尝试将
ends更改为一个数组并使用for (int i = 0 etc对其进行迭代,并将results的预期最大大小传递给results的List 构造函数。 -
有什么理由不为此使用正则表达式?
标签: c# string performance indexof