We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

GDBG Performance (Re-visit)

Hi Clay, I believe this is the 2nd time i am bringing up this issue...but day by day the performance of GDBG is deteriorating... The application we are working on is a trading application with real time updates happening at a interval of 1 seconds... At present the performance in production environment is Using GDBG - 80% CPU Using MS DataGrid - 25% due to corporate policy i cannot upload the source code but application is pretty straightforward.. The GDBG is bounded to a datatable which only 80 rows and 50 columns... and there are four columns that are related to Stock Price Details .. which displays current market stock price details.. as u can see the data held by this column is highly volatile in nature .. so this are the four columns that are updated constantly ... rest of the columns are hardly updated.. in a nutshell out of 80 rows and 50 columns displayed only 4 columns are updated but the update is pretty spread out... so this takes hell lot of cpu cycles... i have pasted below the grid which is used throughout our app.. so would appreciate if you could have a detail look and let us know if we are missing anything.. furthermore in the grid u won''t find binder.suspendbinding and binder.resumebinding() we are doing this in a separate helper class when it receives bulk update from server it invokes the this method. using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using System.Data; using Syncfusion.Windows.Forms.Grid; namespace JPM.EDG.TUI.UICore.Grid { /// /// Summary description for ExtSyncGDBG. /// public class ExtSyncGDBG : GridDataBoundGrid { private Syncfusion.Windows.Forms.Tools.XPMenus.PopupMenusManager popupMenusManager1; private Syncfusion.Windows.Forms.Tools.XPMenus.PopupMenu gridMenu; private Syncfusion.Windows.Forms.Tools.XPMenus.ParentBarItem parentBarItem1; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barFind; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barEnableFilter; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barDisableFilter; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barFreezeRows; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barFreezeCols; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barRelRows; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barRelCols; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barCoverCells; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barResetCover; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barPrintPreview; private Syncfusion.Windows.Forms.Tools.XPMenus.BarItem barPrint; private System.ComponentModel.IContainer components; SyncGridExtender syncGridExt; CurrencyManager gridNavigator; bool autoSized=false; private System.Windows.Forms.Timer updateTimer; bool timedUpdate=false; public ExtSyncGDBG() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitComponent call syncGridExt = new SyncGridExtender(this); this.BaseStylesMap["Column Header"].StyleInfo.Font.Facename = "Tahoma"; this.UseListChangedEvent=true; this.ForceUpdateAfterListChangedEvent =false; this.OptimizeInsertRemoveCells=true; this.VerticalThumbTrack = true; this.Binder.EnableAddNew=false; this.Binder.EnableEdit=false; this.Binder.EnableRemove=false; this.Model.Options.SelectCellsMouseButtonsMask = MouseButtons.Left; this.PrepareViewStyleInfo +=new GridPrepareViewStyleInfoEventHandler(ExtSyncGDBG_PrepareViewStyleInfo); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if( components != null ) components.Dispose(); } base.Dispose( disposing ); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); Syncfusion.Windows.Forms.Grid.GridStyleInfo gridStyleInfo1 = new Syncfusion.Windows.Forms.Grid.GridStyleInfo(); this.popupMenusManager1 = new Syncfusion.Windows.Forms.Tools.XPMenus.PopupMenusManager(this.components); this.gridMenu = new Syncfusion.Windows.Forms.Tools.XPMenus.PopupMenu(this.components); this.parentBarItem1 = new Syncfusion.Windows.Forms.Tools.XPMenus.ParentBarItem(); this.barFind = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barEnableFilter = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barDisableFilter = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barFreezeRows = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barFreezeCols = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barRelRows = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barRelCols = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barCoverCells = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barResetCover = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barPrintPreview = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.barPrint = new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem(); this.updateTimer = new System.Windows.Forms.Timer(this.components); ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); // // gridMenu // this.gridMenu.ParentBarItem = this.parentBarItem1; this.gridMenu.BeforePopup += new Syncfusion.Windows.Forms.CancelMouseEventHandler(this.gridMenu_BeforePopup); // // parentBarItem1 // this.parentBarItem1.CategoryIndex = -1; this.parentBarItem1.ID = ""; this.parentBarItem1.Items.AddRange(new Syncfusion.Windows.Forms.Tools.XPMenus.BarItem[] { this.barFind, this.barEnableFilter, this.barDisableFilter, this.barFreezeRows, this.barFreezeCols, this.barRelRows, this.barRelCols, this.barCoverCells, this.barResetCover, this.barPrintPreview, this.barPrint}); // // barFind // this.barFind.CategoryIndex = -1; this.barFind.ID = "Find"; this.barFind.Text = "Find"; this.barFind.Click += new System.EventHandler(this.barFind_Click); // // barEnableFilter // this.barEnableFilter.CategoryIndex = -1; this.barEnableFilter.ID = "Enable Filter"; this.barEnableFilter.Text = "Enable Filter"; this.barEnableFilter.Click += new System.EventHandler(this.barEnableFilter_Click); // // barDisableFilter // this.barDisableFilter.CategoryIndex = -1; this.barDisableFilter.ID = "Disable Filter"; this.barDisableFilter.Text = "Disable Filter"; this.barDisableFilter.Click += new System.EventHandler(this.barDisableFilter_Click); // // barFreezeRows // this.barFreezeRows.CategoryIndex = -1; this.barFreezeRows.ID = "Freeze Rows"; this.barFreezeRows.Text = "Freeze Rows"; this.barFreezeRows.Click += new System.EventHandler(this.barFreezeRows_Click); // // barFreezeCols // this.barFreezeCols.CategoryIndex = -1; this.barFreezeCols.ID = "Freeze Columns"; this.barFreezeCols.Text = "Freeze Columns"; this.barFreezeCols.Click += new System.EventHandler(this.barFreezeCols_Click); // // barRelRows // this.barRelRows.CategoryIndex = -1; this.barRelRows.ID = "Release Rows"; this.barRelRows.Text = "Release Rows"; this.barRelRows.Click += new System.EventHandler(this.barRelRows_Click); // // barRelCols // this.barRelCols.CategoryIndex = -1; this.barRelCols.ID = "Release Columns"; this.barRelCols.Text = "Release Columns"; this.barRelCols.Click += new System.EventHandler(this.barRelCols_Click); // // barCoverCells // this.barCoverCells.CategoryIndex = -1; this.barCoverCells.ID = "Cover Cells"; this.barCoverCells.Text = "Cover Cells"; this.barCoverCells.Click += new System.EventHandler(this.barCoverCells_Click); // // barResetCover // this.barResetCover.CategoryIndex = -1; this.barResetCover.ID = "Reset Cover Cells"; this.barResetCover.Text = "Reset Cover Cells"; this.barResetCover.Click += new System.EventHandler(this.barResetCover_Click); // // barPrintPreview // this.barPrintPreview.CategoryIndex = -1; this.barPrintPreview.ID = "Print Preview"; this.barPrintPreview.Text = "Print Preview"; this.barPrintPreview.Click += new System.EventHandler(this.barPrintPreview_Click); // // barPrint // this.barPrint.CategoryIndex = -1; this.barPrint.ID = "Print"; this.barPrint.Text = "Print"; this.barPrint.Click += new System.EventHandler(this.barPrint_Click); // // updateTimer // this.updateTimer.Interval = 1000; this.updateTimer.Tick += new System.EventHandler(this.updateTimer_Tick); // // ExtSyncGDBG // this.EnableRemove = true; this.Font = new System.Drawing.Font("Tahoma", 8.25F); this.ShowCurrentCellBorderBehavior = Syncfusion.Windows.Forms.Grid.GridShowCurrentCellBorder.GrayWhenLostFocus; gridStyleInfo1.Font.Bold = false; gridStyleInfo1.Font.Facename = "Tahoma"; gridStyleInfo1.Font.Italic = false; gridStyleInfo1.Font.Size = 8.25F; gridStyleInfo1.Font.Strikeout = false; gridStyleInfo1.Font.Underline = false; this.TableStyle = gridStyleInfo1; this.popupMenusManager1.SetXPContextMenu(this, this.gridMenu); ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); } #endregion protected override void OnPaint(PaintEventArgs pe) { // TODO: Add custom paint code here // Calling the base class OnPaint base.OnPaint(pe); } public bool TimedUpdate { get{return timedUpdate;} set{ timedUpdate=value; if ( value == true ) updateTimer.Enabled=true; } } private void barFind_Click(object sender, System.EventArgs e) { syncGridExt.Find(); } private void barFreezeCols_Click(object sender, System.EventArgs e) { syncGridExt.FreezeCols(); } private void barCoverCells_Click(object sender, System.EventArgs e) { syncGridExt.CoverCells(); } private void barDisableFilter_Click(object sender, System.EventArgs e) { syncGridExt.DisableFilter(); } private void barEnableFilter_Click(object sender, System.EventArgs e) { syncGridExt.EnableFilter(); } private void barFreezeRows_Click(object sender, System.EventArgs e) { syncGridExt.FreezeRows(); } private void barPrint_Click(object sender, System.EventArgs e) { syncGridExt.Print(); } private void barPrintPreview_Click(object sender, System.EventArgs e) { syncGridExt.PrintPreview(); } private void barRelCols_Click(object sender, System.EventArgs e) { syncGridExt.ReleaseCols(); } private void barRelRows_Click(object sender, System.EventArgs e) { syncGridExt.ReleaseRows(); } private void barResetCover_Click(object sender, System.EventArgs e) { syncGridExt.UnCoverCells(); } private void gridMenu_BeforePopup(object sender, Syncfusion.Windows.Forms.CancelMouseEventArgs e) { } private void ExtSyncGDBG_PrepareViewStyleInfo(object sender, GridPrepareViewStyleInfoEventArgs e) { if ( e.RowIndex == 1 && e.ColIndex == this.GridBoundColumns.Count) { this.Model.ColWidths.ResizeToFit(GridRangeInfo.Table()); this.PrepareViewStyleInfo -=new GridPrepareViewStyleInfoEventHandler(ExtSyncGDBG_PrepareViewStyleInfo); } } private void updateTimer_Tick(object sender, System.EventArgs e) { //this.Binder.ResumeBinding(); //this.Binder.SuspendBinding(); } } } Regards Yogi

4 Replies

AD Administrator Syncfusion Team March 15, 2005 07:34 PM UTC

You may want to switch the order of the ResizeToFit call and un-hooking the PrepareViewStyleInfo event, but this is likely only done once (unless you are re-hooking it somewhere) so it probably does not matter. What is SyncGridExtender? What methods have you overriden in it? If you replace SyncGridExtender with GridDataBoundGrid, do you see the same performance problems?


AD Administrator Syncfusion Team March 15, 2005 07:45 PM UTC

SyncGridExtender encapsulate operation related to grid.. pls find below code.. i spoke to syncfusion sales representative a week back and he provided me the link to download the beta version of v3.1.0.1 which has few bug fixes but warned us not move it in productino.. do u think it makes sense to try with the new release ? would it give us a major boost ... any other approach you could think off ? we need a datatable as our whole framework is centered around this concept.. but i don''t think datatable update is a big issue given the fact that it holds only 80 rows using System; using System.Windows.Forms; using Syncfusion.Windows.Forms.Grid; using Syncfusion.Windows.Forms; using System.Drawing.Printing; using System.Data; namespace JPM.EDG.TUI.UICore.Grid { public class SyncGridExtender { GridDataBoundGrid boundGrid; private GridFilterBar gridFilterBar = new GridFilterBar(); private GridMultiColumnSorting multiSort = new GridMultiColumnSorting(); public SyncGridExtender(GridDataBoundGrid grid ) { boundGrid = grid; multiSort.WireGrid(boundGrid,false); } public void Find() { GridFindReplaceDialog frDialog = GridFindReplaceDialog.Instance; foreach(Control ctrl in frDialog.Controls) { if ( ctrl.Name.ToLower() == "buttonreplace" ) { ctrl.Visible = false; } } frDialog.Text = "Find Dialog"; GridFindReplaceDialogSink findReplaceDialogSink = new GridFindReplaceDialogSink(boundGrid); frDialog.SetState(findReplaceDialogSink,"",false); frDialog.Show(); } public void EnableFilter() { if ( !gridFilterBar.Wired ) { gridFilterBar.WireGrid(boundGrid); } } public void DisableFilter() { if ( gridFilterBar.Wired) { gridFilterBar.UnwireGrid(); } } public void ResetFilter() { gridFilterBar.RowFilter = ""; } public void FreezeRows() { boundGrid.Model.Rows.FreezeSelection(); } public void ReleaseRows() { boundGrid.Model.Rows.RestoreFrozen(); } public void FreezeCols() { boundGrid.Model.Cols.FreezeSelection(); } public void ReleaseCols() { boundGrid.Model.Cols.RestoreFrozen(); } public void CoverCells() { GridRangeInfo range = boundGrid.Model.Selections.Ranges.ActiveRange; boundGrid.Model.CoveredRanges.Add(range); } public void UnCoverCells() { GridControlBase grid = boundGrid; if (grid != null) { GridRangeInfoList rl; if (grid.Selections.GetSelectedRanges(out rl, true)) { GridRangeInfo range = rl.ActiveRange; if (!range.IsEmpty) range = grid.Model.CoveredRanges.Merge(range); grid.Model.CoveredRanges.Remove(range); } } } public void PrintPreview() { GridPrintDocument pd = new GridPrintDocument(boundGrid,true); PrintPreviewDialog dlg = new PrintPreviewDialog() ; dlg.Document = pd; dlg.ShowDialog(); } public void Print() { GridPrintDocument pd = new GridPrintDocument(boundGrid); PrintDialog dlg = new PrintDialog() ; dlg.Document = pd; dlg.AllowSelection = true; dlg.AllowSomePages = true; DialogResult result = dlg.ShowDialog(); if (result == DialogResult.OK) { pd.Print(); } } } }


AD Administrator Syncfusion Team March 16, 2005 11:42 AM UTC

Here is a little sample that shows some performance stats. You can use #defines to run it for either a GridDataBoundGrid, a DataGrid, or a virtual GridControl all bound to a DataTable. On a separate thread, updates to the datatable are batched in an arraylist (50 per batch, up to 2-3 batches per second). Then on the UI thread that holds the grid, a timer tick event is raised every second, and in the handler all updates are applied to the grid at this point. On my system, what I see (without any optimizations other than suspending the binding/painting), the datagrid clocks the cpu at roughly 25% on my modest laptop. The GridDataBoundGrid is in the 40-45 range. This is in teh ballpark of the same values you reported I think. I was able to lower the GridDataBoundGrid about 10% into the low 30''s by adding a DrawCell event handler and drawing the cell text at that point in a static manner. This technique essentially bypasses the grid having to to use the Cellrenderer architecture which gives flexibility that is not needed in a rapidly updating bound grid. http://www.syncfusion.com/Support/user/uploads/BoundGridPrototype_f9921293.zip


AD Administrator Syncfusion Team March 16, 2005 01:18 PM UTC

Thx Clay.. very much appreciated ...

Loader.
Up arrow icon