我有一种情况,每次用户按一个键时我需要处理一个20k寄存器的锯齿状数组。我有一个网格,当用户输入时,系统会在网格中显示过滤结果。所以。所以我有一个填充了所有20k寄存器的锯齿状阵列。并且我有一个列表(控件的全局)并且每当用户按下一个键并且只填充过滤的寄存器然后在网格中显示时它就会被清理。
这是代码
the model
public struct PlayerLookUpAdapter
{
[Browsable(false)]
public decimal Id { get; set; }
[DisplayName("Número")]
public String Number { get; set; }
[DisplayName("Nombre")]
public String Name { get; set; }
[DisplayName("Apellido")]
public String Surname { get; set; }
[DisplayName("DNI")]
public String Document { get; set; }
[DisplayName("Estado")]
public String Status { get; set; }
}
private PlayerLookUpAdapter[] _source; // here are the 20k registers
List<PlayerLookUpAdapter> filteredOut = new List<PlayerLookUpAdapter>(); // here the filtered ones
// this code is executed every time the user press a key
private void tb_nro_KeyUp(object sender, KeyEventArgs e)
{
if (!(e.KeyCode.Equals(Keys.Enter) || e.KeyCode.Equals(Keys.Down)) && _source!=null)
{
String text = tb_nro.Text.ToUpper();
if (String.IsNullOrEmpty(text))
{
fg.DataSource = _source;
fg.Refresh();
return;
}
fg.DataSource = null;
filteredOut.Clear();
int length = _source.Length;
for (int i = 0; i < length; i++)
{
PlayerLookUpAdapter cur = _source[i];
if (cur.Number.ToUpper().StartsWith(text) || cur.Surname.ToUpper().StartsWith(text) || cur.Name.ToUpper().StartsWith(text))
filteredOut.Add(cur);
}
fg.DataSource = filteredOut;
SetGridColumnsProperties();
fg.Refresh();
}
else
{
fg.Focus();
}
}
在内存使用和性能方面它是一个很好的解决方案吗?你有什么建议吗?我怎样才能获得更快的速度。它确实很好用,但是如果我有100k寄存器而不是20k呢?
提前致谢。
答案 0 :(得分:3)
我认为这应该是使用树的一个主要例子。
如果你将数据放在树中(我实际上不知道C#/ .Net是否支持树数据结构,或者你自己动手了)。
与在数组中搜索相比,在树中搜索的速度会增加(因为树的搜索速度类似于O(n)= n * log(n))
理论很简单:如果文字中的用户类型,树从这个文字开始进入节点,在这个节点上都是可能的其他节点,依此类推。例如:用户输入“t”你进入“t”节点,然后他输入“e”进入子节点“te”,还有一些其他子节点如“test”,系统将向用户提出这些子节点。
答案 1 :(得分:1)
所有你可以改进你的代码:StartWith方法有一个重载谁也进行字符串比较。你可以把它设置为“OrdinalIgnoreCase”以避免上升所有字符串,但我不认为你会获得很多。 你必须加快搜索速度的唯一方法是将搜索引擎作为Lucene.net。
http://www.codeproject.com/KB/library/IntroducingLucene.aspx
答案 2 :(得分:1)
答案 3 :(得分:0)
预先计算ToUpper()
电话,这样您就不必每次都这样做。您可以维护第二个列表,其中所有字符串都以大写形式存储。
其次,如果将添加键添加到搜索字符串,则应搜索已过滤的列表(而不是整个列表)。新的(较长的)字符串永远不会超出过滤结果。
答案 4 :(得分:0)
您可以在字符串比较中使用StringComparison.OrdinalIgnoreCase
选项,避免在所有字符串上拨打ToUpper
20k次。
理想情况下,首先您需要根据对程序典型使用情况的最佳估算来确定速度有多慢。毕竟premature optimisation is the root of all evil。