开发者

c# Memory performance and speedup

i have a situation, i need to process an jagged array of 20k registers every time a user press a key. I have a grid and while the user is typing the system shows a filtered result in a grid. so. So i have a jagged array filled with all 20k registers. and the i have a list (global to the control) and it´s cleaned up every time the user press a key and filled up with just the filtered registers and then show then in the grid.

Here is the code

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();
            }
        }

is it a good solution in terms of memory usage and performance? have you got any advice? How can i gain more speed. It works realy good, but what about if i got 100k registers instead of 20k?

Thanks in advance.


I think this should be a prime example for using a tree.

If you lay your Data down in a Tree (i actually don't know if C#/.Net supports a Tree Data-Structure, or you have get your own hands dirty).

The Speed you search in a Tree will increase in comparison for searching in an Array (because a Tree gots a search-speed of somehting like O(n)=n*log(n))

The Theory is easy: if a User Types in a Literal, the Tree goes to the Node starting with this Literal, on this nodes are all possible other nodes and so on. For example: The User types in an "t" you go to the "t" Node, then he types in an "e" you go to the subnode "te", there are some other subnodes like "test" and the system will propose the User these subnodes.


firts of all you could improve a bit your code: the StartWith method has an overload who takes the string comparison as well. you could set it as "OrdinalIgnoreCase" to avoid to upper all the strings but I don't think you will gain a lot. The only way you have to speed up you search is go for a Search engine as Lucene.net.

http://www.codeproject.com/KB/library/IntroducingLucene.aspx


You want a prefix tree for this.

Here is one implementation:

  • A Reusable Prefix Tree using Generics in C# 2.0


You could probably use the StringComparison.OrdinalIgnoreCase option on your string comparisons and avoid having to call ToUpper on all your strings 20k times.

Ideally, first you need to decide how slow is too slow based on your best estimates for typical usage of your program. After all premature optimisation is the root of all evil.


Precalculate the ToUpper() call so you dont have to do it every time. You could maintain a second list where all the strings are stored uppercase.

Secondly you should search the filtered list (instead of the whole list) in case a key is added to the search string. The new (longer) string can never be outside of the filtered results.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜