c#内存性能和加速
本文关键字:加速 性能 内存 | 更新日期: 2023-09-27 18:00:30
我有一种情况,每次用户按键时,我需要处理一个由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();
}
}
就内存使用和性能而言,它是一个好的解决方案吗?你有什么建议吗?我怎样才能获得更高的速度。它运行得很好,但如果我有10万个寄存器而不是2万个呢?
提前谢谢。
我认为这应该是使用树的一个主要示例。
如果你把数据放在树中(我实际上不知道C#/.Net是否支持树数据结构,或者你自己动手了)。
与在数组中搜索相比,在树中搜索的速度会增加(因为树的搜索速度为O(n)=n*log(n))
理论很简单:如果一个用户在一个Literal中键入,树会从这个Literal开始转到节点,在这个节点上所有可能的其他节点等等。例如:用户键入"t"你转到"t"节点,然后他键入"e"你转到子节点"te",还有一些其他子节点,比如"test",系统会向用户提出这些子节点。
首先,您可以稍微改进您的代码:StartWith方法有一个重载,它也会进行字符串比较。您可以将其设置为"OrdinalIgnoreCase",以避免将所有字符串设置为上限,但我认为您不会获得太多好处。加快搜索速度的唯一方法是使用Lucene.net.这样的搜索引擎
http://www.codeproject.com/KB/library/IntroducingLucene.aspx
您需要一个前缀树。
这里有一个实现:
- C#2.0中使用泛型的可重用前缀树
您可以在字符串比较中使用StringComparison.OrdinalIgnoreCase
选项,避免对所有字符串调用ToUpper
20k次。
理想情况下,首先你需要根据你对程序典型使用情况的最佳估计来决定速度有多慢。毕竟,过早的优化是万恶之源。
预先计算ToUpper()
调用,这样就不必每次都这样做。您可以维护第二个列表,其中所有字符串都以大写形式存储。
其次,您应该搜索过滤后的列表(而不是整个列表),以防关键字被添加到搜索字符串中。新的(较长的)字符串永远不能在筛选结果之外。