Hi,
I am using groups to restrict the user rearranging columns so that they can only be moved within a group. However assigning the column to a group is really expensive and because of this it I can't use it because it is too slow.To illustrate this I created a simple windows forms project with an ultragrid, an ultratexteditor to enter the number of columns to create, an ultralabel to display the elapsed time and an ultrabutton to kick off the column creation - it just builds a datatable with the number of columns entered, assigns it to the grid and then iterates over the columns assigning each one to one of two groups.Here is the time taken for 100, 200 and 500 columns, as you can see the performance degrades exponentially100 columns: 0.359s200 columns: 1.437s500 columns: 16.563sThe code is here: public partial class Form1 : Form { UltraGridGroup groupA, groupB; public Form1() { InitializeComponent(); groupA = ultraGrid1.Rows.Band.Groups.Add("Group A"); groupB = ultraGrid1.Rows.Band.Groups.Add("Group B"); ultraGrid1.DisplayLayout.Override.AllowColMoving = AllowColMoving.WithinGroup; } private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e) { } private void ultraButton1_Click(object sender, EventArgs e) { DateTime start = DateTime.Now; int columns = int.Parse(ultraTextEditor1.Text); DataTable dt = new DataTable(); for(int i = 0; i < columns; ++i) { dt.Columns.Add(i.ToString()); } ultraGrid1.DataSource = dt; // Assign columns to one of the two groups ultraGrid1.BeginUpdate(); ultraGrid1.Rows.Band.GroupHeadersVisible = false; foreach(UltraGridColumn column in ultraGrid1.Rows.Band.Columns) { column.Group = column.Index < 10 ? groupA : groupB; } ultraGrid1.EndUpdate(); ultraLabel1.Text = (DateTime.Now - start).TotalMilliseconds.ToString(); }Using a profiler on the example with 200 columns I can see that 98% of the time is spent in UltraGridColumn.set_Group, within there it calls UltraGridColumn.GetActualWidth 18,200 times, and the main culprit is the UltraGridBand.get_ConContainsColumnWithVisibleHeaderCheckBoxOnTopOrBottom() function that takes 84.78% of the total time. Internally in total it has created 18,200 enumerators and called MoveNext 3,658,200 times!!!!!In actual fact I do know which group I want each column to be assigned to when I first created the data table, however this is only a grid concept so I have no choice but to manipulate it afterwards.Is there a more efficient way to allocate columns to groups? As it is I will have to give up on groups altogether as it is possible that we have a fair number of columns in our grid.The profiler breakdown looks like this100.00 % ultraButton1_Click - 16317 ms - 1 call - grid_group_perf.Form1.ultraButton1_Click(Object, EventArgs) 98.65 % set_Group - 16096 ms - 200 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.set_Group(UltraGridGroup) 98.64 % SetGroup - 16095 ms - 200 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.SetGroup(UltraGridGroup, Int32, Int32) 98.41 % InternalAdd - 16057 ms - 200 calls - Infragistics.Win.UltraWinGrid.GroupColumnsCollection.InternalAdd(UltraGridColumn, Int32, Int32) 98.17 % AdjustGroupWidth - 16018 ms - 200 calls - Infragistics.Win.UltraWinGrid.GroupColumnsCollection.AdjustGroupWidth(Boolean, Boolean, Boolean) 96.42 % GetGroupWidthRange - 15733 ms - 200 calls - Infragistics.Win.UltraWinGrid.GroupColumnsCollection.GetGroupWidthRange(Boolean, Boolean, Int32 &, Int32 &, Int32 &) 95.84 % GetActualWidth - 15637 ms - 18200 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.GetActualWidth() 95.82 % GetActualWidth - 15635 ms - 18200 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.GetActualWidth(Boolean) 95.71 % get_Width - 15616 ms - 18200 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.get_Width() 90.45 % get_CardLabelSize - 14759 ms - 18200 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.get_CardLabelSize() 90.06 % VerifyCardLabelSizeCache - 14695 ms - 18200 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.VerifyCardLabelSizeCache() 84.78 % get_ContainsColumnWithVisibleHeaderCheckBoxOnTopOrBottom - 13834 ms - 18200 calls - Infragistics.Win.UltraWinGrid.UltraGridBand.get_ContainsColumnWithVisibleHeaderCheckBoxOnTopOrBottom() 37.30 % get_HeaderCheckBoxAlignmentResolved - 6086 ms - 3640000 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.get_HeaderCheckBoxAlignmentResolved() 16.25 % get_HiddenResolved - 2652 ms - 3640000 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.get_HiddenResolved() 13.49 % get_IsHeaderCheckBoxVisible - 2202 ms - 2486250 calls - Infragistics.Win.UltraWinGrid.UltraGridColumn.get_IsHeaderCheckBoxVisible()ThanksMartinp.s. I'm using the latest 2009.1 hotfix
Hi Martin,
Yeah, it looks like this is something we should look at improving. There's no reason it should take this long.
I'm forwarding this thread over to the Infragistics Developer Support group so they can write this up for review by the developers. Hopefully, we can do something about this for the next service release.
Yes I have read the performance guide, the code I posted had already wrapped the group assignment between beginupdate and endupdate calls...
I have attached the full example project for your convenience.
Many thanks,
Martin
Have you read this- WinGrid Performance Guide ?
The section on BeginUpdate and EndUpdate might help.
If that doesn't help, can you post your sample project which demonstrates this so I can take a look? There's really no reason why this should take so long as far as I can see.
Not sure if you have some other restrictions but using a RowLayout might be another option.
There are some limitations with RowLayouts however.
Nick