在listview中进行高效搜索

时间:2015-05-04 18:13:45

标签: c# linq listview windows-runtime

我正在使用Linq搜索并在WinRT(Windows Phone 8.1)上的ListView中显示特定字符​​串。 这是我目前的方法:

string value = (string) sender.Text.ToLower();
if (value == "")
{
    AirportsList.ItemsSource = _airports.CountryList;
}
else
{
    List<Airport> queryList = _airports.AirportList
        .Where(airport => airport.IcaoId.ToLower().Contains(value) 
                      || airport.IcaoName.ToLower().Contains(value) 
                      || airport.City.ToLower().Contains(value) 
                      || airport.Country.ToLower().Contains(value)).ToList();
    AirportsList.ItemsSource = queryList.ToList();
}

由于每次都必须创建itemssource,因此速度很慢而且很迟钝。有更高效的方式吗?

1 个答案:

答案 0 :(得分:1)

我想创建queryList不一定是缓慢的部分。这只是一个List<Airport>,任何硬件都可以用最小的开销来实例化。我想,缓慢的部分是必须检查所有可能机场的四个不同属性的价值,其中可能有很多。此外,对于每个属性,您正在搜索它是Contains字符串,而不是它只是在开头(通过StartsWith)。这意味着必须对每个属性进行线性搜索以获得结果。

幸运的是,搜索项目是一个非常常见的计算问题;因此,有许多解决方案开发人员比我自己更加聪明地设计用于加速搜索,或者至少使他们似乎 snappy。我建议你看看下面列出的项目的组合(并搜索更多!)。我不能在没有写出长篇大论的情况下提供它们(可能是另一个SO'er会有所帮助),但希望它们能帮助你进行搜索!

  • 在收集结果时将结果返回给用户界面 - 此方法不需要对您的方法进行基本更改,也不会使其更快,但是即时的UI反馈是在心理上讲非常重要,并引起用户的注意。
  • 缩小查询 - 他们是否在搜索LHRTPE或任何三字母短语?他们可能正在搜索ICAO ID。首先通过ICAO ID执行搜索,然后尽快将它们回显到UI。检查他们的IP,他们是从英国的计算机上搜索的吗?如果是,您可以优先考虑英格兰的机场等。在许多情况下,这将完成大多数人的搜索,而无需经历所有可能的选择。当然,在这些快捷方式之后进行完全排列搜索会导致他们进行非标准搜索。
  • 子集以前的查询答案 - 如果他们搜索了Lon并且搜索了London HeathrowLondon GatwickLondrina,那么请关注-Londo的搜索只会返回这些响应的子集。这要求您保持先前请求(和响应)的状态,并且在实践中可能很复杂。
  • 预先分配和索引_airports.AirportList并使用不同的搜索算法 - 目前,您正在线性搜索具有O(n)复杂度的机场。如果您最初使用StartsWith而不是Contains进行搜索,那么使用二进制搜索会将algorythm降低到O(log n),如果有很多机场,最终会更快。将您的_airports.AirportList IcaoIdIcaoNameCityCountry分成不同的索引/列表(如果您有备用内存)并对其进行二进制搜索
  • 如果这不起作用,请继续饮酒(并进行微观优化) - 您可以先发制人ToLower _airports.AirportList _airports.AirportList这样您就没有在搜索时不断降低它们。您可以利用缓存优化并将List<IcaoId>展平为并行List<IcaoName>this &amp; that等。您可以统计分析客户的搜索习惯并优化您的搜索范围(例如,90%是使用两个机场,总是有那些机场顶部的搜索堆)。您可以将搜索卸载到3 rd 派对服务上, 具有计算能力,几乎可以即时完成(我严重地考虑到这一点)。您可以多线程整个过程。你可以用C ++重写它,并且当你2个月前写的一个类在你的手机上泄露内存时会感到烦恼。你可以找到证据表明你的老板在性丑闻中勒​​索他/她,完全避免这个问题,等等。