Showing posts with label Performance. Show all posts
Showing posts with label Performance. Show all posts

Thursday, October 15, 2009

[.NET] XmlDocument VS XmlReader

To cut a long story short I recently learned (thanks to a co-worker) that XmlDocument performance sucks.

It's very handy to manipulate XML stuff with XmlDocument because it comes with all the DOM stuff, and for example you can use XPath for node selection like this:
// load up the xml doc
XmlDocument doc = new XmlDocument();
doc.Load(filename);

// get a list of all the nodes you need with xPath
XmlNodeList nodeList = doc.SelectNodes("root/whatever/nestedWhatever");
The above is quite cool and it works just fine if you're not loading hundreds of files for a total size of hundreds of MBs, in which case you'll notice a lethal blow to performance.

If you need speed you wanna go with XmlReader, a bare bones class that will scan the old way (forward only) element after element your XML file. Bad thing is that you won't have all the nice DOM stuff, so you'll have to manually parse elements retrieving innerText and/or attribute values. An example:
XmlReader xmlReader = XmlReader.Create(fileName);

while (xmlReader.Read())
{
//keep reading until we see my element
if (xmlReader.Name.Equals("myElementName") && (xmlReader.NodeType == XmlNodeType.Element))
{
// get attributes (or innerText) from the Xml element here
string whatever = xmlReader.GetAttribute("whatever");
// do stuff
}
}
I can't be bothered benchmarking as it bores the sh*t out of me - but performance increases a whole lot with XmlReader, and if you want figures to look at you can find plenty on google (this guy here did a pretty good job for example) and here's another good overview of XML classes (from Scott Hanselman's blog).

Anyway - here comes the common sense advice - whatever you're doing go with XmlDocument, if it's too slow for you needs switch over to XmlReader and you'll be grand.

Thursday, September 3, 2009

How to check if WPF is using Hardware or Software Rendering?

In general, software rendering will usually kick-in if your machine doesn't support DirectX or if the drivers installed are not working correctly (for whatever reason). WPF is entirely built on Direct3D, and software rendering means your WPF app will run painfully slow.

In borderline scenarios, such as running on portable device where hardware capability is constrained, you might find yourself in a bit of a mexican standoff situation where you don't know if the bottleneck is the hardware itself or the problem is just that hardware acceleration is not working and the system falls back to software rendering. So, how do you check if software rendering is kicking in?

You can do this from code querying the RenderCapability.Tier property, as follows:
//shifting some 16 bits will do the trick
int renderCapabilityTier = (RenderCapability.Tier >> 16);
The int above can have three possible values:
  • 0 --> you're screwed - no hardware acceleration
  • 1 --> you're half screwed - you got some hardware acceleration
  • 2 --> you're good to go with full blown hardware acceleration
You might also wanna run the DirectX diagnostic tool (just run dxdiag.exe) to double check the state of your hardware acceleration (check the display tab) and, since we are at it, the new WPF profiler.

Friday, February 29, 2008

[.NET] Strings gone wild

Are .NET strings evil? Not at all, but there is an exception to this: where in big packs strings can become very dangerous for performance of your app. Let's see why and how to avoid this.

System.String is a reference type implemented to behave as a value type; Strings instances of this type are IMMUTABLE : When a string is created if you modify it a new one is created and the old one is abandoned to the care of the garbage collector. For example with the following code we are creating 3 strings not just one, and we're keeping a reference to the last one that's been created:
string mySillyString = "hey";
mySillyString += " hey ";
mySillyString += " hey!";

This is fine if you are doing just a few of these operations, but if you are going down with massive string manipulation (maybe within loops), all the overhead associated with the string creation will cause your app to slow down, plus all the abandoned strings will pack together and go wild, giving an hard time to the garbage collector, and eventually feckin'up you app performances.

In such a case we should use a way to operate on strings dinamically. Without using any unsafe block of code, we can easily do this trying to use when possible string methods like Join, Concat and Format (the latter - as we all know - very useful). But the real rock star here is the StringBuilder: it sure carries a bit of overhead, so it might not worth it to use it just for a few string manipulations, but if you plan to do more than 10 operations you should use it as a rule. In case of fast machines, even more than 5 operations might justify the use of a string builder (as indicated on this MSDN paper: http://msdn2.microsoft.com/en-us/library/ms973839.aspx ).
Here an example of how to use the StringBuilder:

System.Text.StringBuilder myKickAssStringBuilder = new
System.Text.StringBuilder(30);
myKickAssStringBuilder.Append("hey ");
myKickAssStringBuilder.Append(" hey ");
myKickAssStringBuilder.Append(" hey!");
myKickAssStringBuilder.Append(" hey Stoopid");
myKickAssStringBuilder.Append("!");
string myLonelyString = myKickAssStringBuilder.ToString();


All for today. Kick-Ass out there.

Thursday, February 21, 2008

[.NET] Built-in Types Performance Tip

Here's something not everyone knows about .NET framwork built-in types performance:
Quoting from MCTS Training Kit for Exam 70-536, .NET Framework 2.0 - Application Development foundation:



"The runtime optimizes the performance of 32-bit integer types (Int32 and UInt32), so use those types for counters and other frequently accessed integral variables. For floating-point operations, Double is the most efficient type because those operations are optimized by hardware."


Let's be honest: in average development conditions this won't make much of a difference. Depending on what kind of app your working on, tough, it means that -if you're not working on very constrictive memory conditions- even if you need just a float (4 bytes) to represent numeric values, you should go for a double in order to optimize your floating point operations, and so on.


It's just kind of nice to know this, so next time you'll meet a memory maniac -who's using short variables as counters- you'll have a concrete reason to laugh at him.

Thursday, January 24, 2008

[ASP.NET, SQLServer] How to fix Performance Problems - guidelines

Scenario/Problem: You have an ASP.NET (framework x.x.) application and some pages are taking forever to load up.

Guidelines: Follow these steps:
  1. If using DBs: Are you indexing your DB? If not you should consider it (up to 30% speed increase, depending on you DB design)
  2. Check your controls ViewState: are you sending unuseful stuff back and forth? If you're generating/populating dinamically some control you should disable its viewstate. Use ASP.NET trace to check controls viewstate size (DRAMATIC speed increase, depending on your app)
  3. Look at your T-SQL stored procedures: are you abusing temporary tables or dynamic SQL execution? If so it's not a good idea, use SQL profiler to check for stored procedures recompilation-execution time. If you don't have stored procedures you probably should use them
  4. Look at your code behind: are you round-tripping more than you need? Are you sharing open connections to DB when you can (use SQL Profiler to spot how many connections you are opening and closing)? Are you mis-using some controls (huge drop down list can cause major delays)? Use ASP.NET trace to locate hot-spots and long latencies.

Real World Case: I don't feel much of a butcher these days: I was working on a web app [ASP.NET 1.1, SQLServer2000] developed by someone else and i realized butchery is a fine art and I still got a long way to go.

My main task was to speed things up. It was taking 18 seconds to load a single page, with an average amount of data (nothing major). I first tried to put some indexes on the DB (1), which didn't have any, but not having at the time much experience on DB indexing I put my life in the hands of the Enterprise Manager Index Tuning Wizard (painful experience), knowing it would have butchered my DB, but hopefully just a bit, speeding up things for me in the end. It happened, but from 16-18 seconds the guilty page went down to 12-13, which was something but not what I was hoping. The wizard claimed a 28% speed increase: true, but not enough.

After this delusion, I went on inspecting the trace (enable it setting Trace="true" in the top page declaration, or @ app level from web.config) and I noticed KBytes of useless stuff being sent back and forth as ViewState (2). The app had a coulple of user controls dynamically generated every Page.Load, so I just disabled the ViewState for those (EnableviewState = "false") and the app speed dramatically increased (50% in my case). Good, but still it was taking 6-7 goddamn seconds to load. I also took off the SmartNavigation="true" page property: it might be the pre-AJAX coolest thing but it's deprecated and it saved me almost 2 seconds: down to 5.

I started looking at the code, spotting un-necessary open/close operations for connections that could've been shared, loads of butchery in there, of the finest quality, and I noticed ALL the stored procedures were being recompiled (3) because of a massive use of temporary tables and dynamic SQL, even when non necessary (if the stored procedure is being recompiled there's no gain speed, ergo no point in having it as stored procedure). I didn't really want to change the code, a work of art is a work of art, so I decided to roam a little bit more through the trace looking for hot-spots.

I noticed the page was laoding pretty fast looking at the trace latencies. I put some Trace.Warn("HereandThere") but there was nothing major, the whole page was taking only around 1 sec to process and render, but I was still seeing the content trhough the browser after 5 secs. Then again a look at the ViewState and controls sizes and it happened: I saw a 900KB dropdownlist (4). Turned out that drop down was being populated with more than 10.000 record (yes > 10^4) and the browser was obviously taking forever (around 3 secs) to load it. Took that out (set up a popup with only the dropdown for that selection) and EUREKA: loading time went down to 1-3 secs, which considering shitty server and crappy network is more than acceptable (compare it with 18 seconds if you don't agree).

As I said, there was (and there is) a lot more to change and optimize in this app, as per stored procedures code and code behind, but the art is art and I wanna keep this mess untidy as long as I can, to inspire me and to remind me what butchery truly means.