iPad上的MonoTouch:如何更快地进行文本搜索?

new*_*man 2 c# algorithm optimization search xamarin.ios

我需要根据相对较大的列表中的用户输入进行文本搜索(每行大约37K行,每行50到100个字符).输入每个字符后进行搜索,结果显示在a中UITableView.这是我目前的代码:

if (input.Any(x => Char.IsUpper(x)))
    return _list.Where(x => x.Desc.Contains(input));
else
    return _list.Where(x => x.Desc.ToLower().Contains(input));
Run Code Online (Sandbox Code Playgroud)

它在运行模拟器的MacBook上运行良好,但在iPad上运行速度太慢.

我观察到有趣的事情是,随着输入的增长,它需要更长更长的时间.例如,说"examin"作为输入.进入e后约1秒,x后2秒,a后5秒,但m后28秒,依此类推.为什么?

我希望有一种简单的方法来改进它.

pou*_*pou 5

始终注意避免时间敏感代码中的内存分配.

例如,我们经常生成代码string而不经常实现分配,例如

x => x.Desc.ToLower().Contains(input)
Run Code Online (Sandbox Code Playgroud)

那将分配一个字符串来返回ToLower.根据您的描述,这将发生很多次.您可以通过以下方式轻松避免此问题

x = x.Desc.IndexOf ("s", StringComparison.OrdinalIgnoreCase) != -1
Run Code Online (Sandbox Code Playgroud)

注意:只需选择StringComparison.*IgnoreCase符合您需要的选项即可.

LINQ也很不错,但在许多情况下它隐藏了分配 - 可能不是你的情况,但测量是提高速度的关键.在那种情况下使用另一种算法(如在另一个答案中建议)可以给你更好的结果(但请记住分配;-)

更新:

Contains(string)经过几次检查,Mono 将致电以下内容:

CultureInfo.CurrentCulture.CompareInfo.IndexOf (this, value, 0, length, CompareOptions.Ordinal);
Run Code Online (Sandbox Code Playgroud)

其中,您的ToLower要求是使用StringComparison.OrdinalIgnoreCase是您现有代码的完美(即相同)匹配(它没有进行任何特定于文化的比较).