|
|
SuspendLayout / ResumeLayout performance issues
Last post 05-17-2006, 1:24 PM by seanl. 9 replies.
-
05-11-2006, 2:21 AM |
-
laxtyler
-
-
-
Joined on 11-29-2005
-
-
Posts 18
-
-
|
SuspendLayout / ResumeLayout performance issues
Hi,
I am working on an application that inserts data into a FarPoint spread control on a regular timer. That timer runs every 200 ms. I've noticed that if I call SuspendLayout/ResumeLayout each time the timer runs, my application runs at 50% CPU, (on a hyper-threaded machine, so I assume its 100% on a non-hyperthreaded CPU) even if I don't touch a single cell.
I seem to be stuck - if I don't call SuspendLayout and ResumeLayout, my performance can be slow when I set the values in a number of cells. On the other hand, if I do call SuspendLayout/ResumeLayout, I have an immediate performance overhead hit as I mentioned above.
What's the best way to create an app that needs to regularly update data into FarPoint at a reasonably high frequency?
Thanks,
Tyler
|
|
-
05-11-2006, 2:26 AM |
-
laxtyler
-
-
-
Joined on 11-29-2005
-
-
Posts 18
-
-
|
Re: SuspendLayout / ResumeLayout performance issues
Also, as a follow-up, should I set AutoCalculation to false and then true on this timer update as well?
The number of cells that I update per timer call can vary a lot, sometimes I need to update 6-10 cells, sometimes 500 cells. I do have a number of formulas in the sheet.
FYI, this is the same layout/formulas that work in Excel using RTD to push real-time data on a 200 ms timer into Excel. Excel runs at about 6-7% CPU during reasonably high numbers of updates.
Tyler
|
|
-
05-11-2006, 2:11 PM |
-
seanl
-
-
-
Joined on 02-13-2003
-
Morrisville, NC, USA
-
Posts 1,098
-
-
|
Re: SuspendLayout / ResumeLayout performance issues
SuspendLayout will prevent the SpreadView from recomputing the layout of columns, rows, and cells when changes are made to the sheet. The layout objects are not part of the public API, but they cache all of the layout information required to paint the sheet, like the column widths, row heights, cell spans, cell overflows and the rectangles of cell notes that are always visible (Cell.NoteStyle = NoteStyle.StickyNote). If you are making lots of changes to the sheet in a block of code, using SuspendLayout will prevent the SpreadView from doing redundant intermediate recalculations of the layout objects as each change is made, and using ResumeLayout(true) will recompute the layout once after all of your changes are made. That will increase performance greatly, but there is more you can do depending on what features your sheets require.
If you are not using sticky notes, then you can set AutoUpdateNotes to false to prevent the SpreadView from checking for sticky notes that need to be made visible or hidden or moved. If you are using AllowCellOverflow, turning that off will greatly increase the performance of the layout calculations, because that feature requires lots of text width calculations on each change to the data in a cell. Since you are using formulas, setting AutoCalculation to false before your updates and then setting it back to true and calling Recalculate afterwards will eliminate redundant intermediate recalculations of your formulas.
Some other things you could do would be to reduce the size of the control or show fewer columns and rows at once (the layout objects only calculate the visible portion of the sheet), or implement your own sheet model objects (like your own data model object implementing ISheetDataModel) which remove features that you do not require (for example, if you do not require data binding, the data binding interfaces do not need to be implemented).
Sean Lawyer Spread.NET Product Manager GrapeCity PowerTools
|
|
-
05-11-2006, 4:34 PM |
-
laxtyler
-
-
-
Joined on 11-29-2005
-
-
Posts 18
-
-
|
Re: SuspendLayout / ResumeLayout performance issues
Thanks a lot for your answer - I will look into the things you mentioned in more detail.
Does it make sense that SuspendLayout/ResumeLayout would consume so much CPU time if no cells were changed while the layout was suspended, or is there something we need to look at there? I literally turned off any updating of cells in my application, so each clock tick (every 200 ms), there would just be a call to Suspend/Resume, and I saw constant 50% CPU usage. If I commented out the calls to Suspend/Resume, my CPU usage was 0%.
Do you recommend still calling Suspend/Resume around my cell updates if I'm updating on a clock? As I mentioned, I'll try the changes you mentioned above to see if that makes a difference as well.
Also, if I were to use my own DataModel and still wanted formula capabilities, what's the right way to do that? We don't do any data binding, so we don't need those capabilities - we set values in the sheet directly. The BaseDataModel doesn't support formulas, so I don't want to lose that functionality.
Thanks,
Tyler
|
|
-
05-11-2006, 5:00 PM |
-
laxtyler
-
-
-
Joined on 11-29-2005
-
-
Posts 18
-
-
|
Re: SuspendLayout / ResumeLayout performance issues
Following on the last message, I tried setting AutoUpdateNotes, AllowNoteEdit, AutoGenerateColumns, AllowCellOverflow, CellNoteIndicatorVisible, and EnableCrossSheetReference all to false since I wasn't using any of those. Unfortunately, calling Suspend/Resume one every 200 ms without touching any cells still causes a 50% CPU load.
Also, I'm using VS 2005, and have tried adding the GDI TextRenderer. However, when I try to run, I see a Managed Debugging Assistant error saying that "FarPoint.Win.TextRenderer failed to load in the 'Load' binding context of the AppDomain with ID 1. The cause of the failure was: System.IO.FileLoadException: Could not load file or assembly 'FarPoint.Win.TextRenderer, Version=2.5.2001.2005, Culture=neutral, PublicKeyToken=327c3516b1b18457' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) File name: 'FarPoint.Win.TextRenderer, Version=2.5.2001.2005, Culture=neutral, PublicKeyToken=327c3516b1b18457'"
It appears that the file can actually be found (its in my references okay), but there is a problem with the manifest describing the TextRenderer assembly...
Will using the GDI TextRenderer improve performance? If so, do you know how to get the renderer into use? Lastly, is there an easy way to know programmatically if the GDI renderer loaded succesfully?
Overall, we need to figure out how to get data into FarPoint at a high frequency (several hundered cell updates on a clock running at least 5 times a second) with low CPU usage, < 5%. Is this achievable?
Thanks.
|
|
-
05-15-2006, 5:10 PM |
-
laxtyler
-
-
-
Joined on 11-29-2005
-
-
Posts 18
-
-
|
Re: SuspendLayout / ResumeLayout performance issues
Hi, I wanted to see if there were any thoughts about the previous two posts? Thanks.
|
|
-
05-16-2006, 10:10 AM |
-
seanl
-
-
-
Joined on 02-13-2003
-
Morrisville, NC, USA
-
Posts 1,098
-
-
|
Re: SuspendLayout / ResumeLayout performance issues
It is normal to see the MDA warning about the text renderer assembly, if you have those MDAs turned on. It is nothing to worry about. The Spread attempts to load that assembly during its initialization if it sees that the framework version is 2.0 or greater, but it does not have a dependency on the text renderer assembly so that its use is optional (all calls made into the text renderer assembly use reflection). The text renderer assembly should increase performance overall a bit (I think) because the native GDI drawing code should be faster, and provide an overall gain over the cost of dynamic calls using reflection together with the extra text extent calculations involved in drawing the text using GDI+.
If you force the sheet to repaint 5 times a second, I do not know that there is any way to keep the CPU usage that low (<5%). I assume that you are calling ResumeLayout(true) to force the layout to be recalculated. If you would like me to look into possible performance issues in the Spread paint and layout code, please put togther a small sample that shows the performance bottleneck you are seeing and I will look into it in detail using some profiling tools. We are starting to look into development for the next version of Spread, and performance is one of the big line items planned for that release, so any assistance you can provide in identifying areas for improvement would be much appreciated.
It sounds to me though, like you might not actually need to be recomputing the layout at all in your timer. If the changes you are making involve only changes to values in cells, and you are not using cell overflow or cell merging, and you are not changing the widths or heights or rows or columns and you are not scrolling the sheet, then recomputing the layout is not necessary. You could try changing the code to call ResumeLayout(false) and simply invalidate the Spread to force a repaint to update the changed cells, and see how that speeds things up.
Sean Lawyer Spread.NET Product Manager GrapeCity PowerTools
|
|
-
05-17-2006, 12:59 PM |
-
laxtyler
-
-
-
Joined on 11-29-2005
-
-
Posts 18
-
-
|
Re: SuspendLayout / ResumeLayout performance issues
To be clear, when we see the TextRenderer MDA exception mentioned above, are you saying that everything is okay, and we're sucessfully loading the GDI TextRenderer? My feeling would be that the MDA exception indicates we are not succesfully loading the FarPoint text renderer and therefore are using GDI+.
How can we determine for sure we are using the GDI renderer? The scheme of simply including a class in my assembly means I can only assume the GDI renderer is actually being loaded, but given the MDA exception, now I'm not sure. If the MDA exception is a sign that its not being loaded, what do I need to do to succesfully load it? I have included the FarPoint.Win.TextRenderer
Also, your e-mail says you think GDI is faster. I thought that a gain in paint performance was the main point of using the GDI renderer?
|
|
-
05-17-2006, 1:15 PM |
-
kchipalowsky
-
-
-
Joined on 05-17-2006
-
-
Posts 1
-
-
|
Re: SuspendLayout / ResumeLayout performance issues
I may be a little confused here, but it looks to me like the FarPoint.Win.TextRenderer assembly is incorrectly signed and therefore unusable. I created an empty project and added a reference to that assembly. The otherwise empty C# project just tries to instantiate a TextRenderer: public Form1() { InitializeComponent(); FarPoint.Win.TextRenderer. TextRenderer renderer = new FarPoint.Win.TextRenderer.TextRenderer(); }
The program compiles correctly, but when I try to run it I see the following exception. The "Strong name validation failed" message is what worries me. What does this mean? This is very similar to the error message that was reported earlier in this thread.System.IO.FileLoadException was unhandled Message="Could not load file or assembly 'FarPoint.Win.TextRenderer, Version=2.5.2001.2005, Culture=neutral, PublicKeyToken=64fbbfff0d07f045' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)" Source="WindowsApplication1" FileName="FarPoint.Win.TextRenderer, Version=2.5.2001.2005, Culture=neutral, PublicKeyToken=64fbbfff0d07f045" FusionLog="" StackTrace: at WindowsApplication1.Form1..ctor() at WindowsApplication1.Program.Main() in C:\Documents and Settings\kchipalowsky\My Documents\Visual Studio 2005\Projects\WindowsApplication1\WindowsApplication1\Program.cs:line 17 at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() Thank you, Kevin Chipalowsky
|
|
-
05-17-2006, 1:24 PM |
-
seanl
-
-
-
Joined on 02-13-2003
-
Morrisville, NC, USA
-
Posts 1,098
-
-
|
Re: SuspendLayout / ResumeLayout performance issues
The MDA is indicating that there was a call made to Assembly.Load which failed to load the requested assembly. Again, this is nothing to worry about if you do not intend to use the text renderer assembly for GDI+ text rendering, as this exception being reported is expected and trapped in our code, and the Spread is designed to fall back on the GDI+ text rendering in that case. If you are seeing that notification, then the Spread is still using GDI+ for text rendering. Please be sure that you have the latest maintenance release, as there was a bug in the initial release which would prevent the text renderer assembly from getting loaded correctly. The latest maintenance release is version 2.5.2003.2005, and can be downloaded from http://www.clubfarpoint.com. It is not necessary to include the text renderer assembly in your project references; it just needs to be in the bin folder with the EXE or in the GAC so that the Spread assembly can find it when it tries to load it (adding it to your project references will not hurt anything though). I think using the text renderer assembly will improve performance because the drawing APIs in the Windows GDI library are implemented with optimized C and assembly code, and are pixel-based and do not have the extra layers of resolution independent rendering that are in GDI+. The GDI+ text rendering in Spread uses calls to MeasureCharacterRanges and DrawString to draw the text, and supporting the various TextOrientation features requires lots of calls to MeasureCharacterRanges to compute the layout of the text. This code should be much faster using the older GDI DrawText function to measure the text extents.
Sean Lawyer Spread.NET Product Manager GrapeCity PowerTools
|
|
FarPoint Forums Home
|
|
|