Steps To Figuring Out Performance Issues

Programming performance issues can be a frustrating and time-consuming problem for developers. However, tracking down these issues is a crucial step in creating software. Here are some steps that developers can take to track down programming performance issues:

The first thing to do is ALWAYS hook up a profiler to your code, reproducing your issue, and measuring what is causing it. Performance issues are often not obvious and if you don’t profile you’ll waste a bunch of time speeding up things that don’t matter(or just hide the base issue).

In my experience, here are the main areas you get performance issues:

  • DB
  • DB
  • DB
  • DB
  • API Calls
  • External Access

A little hint: most of the time you are optimizing your code and not these other areas, you are reducing readability and not significantly impacting your load times for users.

Outside of these issues, it is often something silly a developer is doing. Some of the things I’ve seen:

  • Pulling the whole table down(all 1 million records) then filtering on the application server
  • Creating new instances of classes that do a lot of work on creation instead of reusing them
  • Really bad exception throwing that is used as control flow
  • Sending down 8 megabytes of HTML for a page, of which 6 megabytes is double escaping special characters (sending ////” instead of “)

Once you figure out where the main areas of slowness, it’s time to refactor!

Form Validation is No Fun

Over the years Software Engineering has gone through many iterations of best practices. Form field validation is no exception to this.

The morale of the story here is stop rolling your own validation. This is one of those things that seem super easy to do, so you just quick roll your own and then move on. Except you never move on because you’ll get tickets to fix stuff until the end of time.

Let’s talk about email validation as an example:

[email protected]
Early on, email was validated by checking if the email had letters, an @ sign, letters, and then ended with .com. This worked great until…

[email protected]
People started using subdomains for email. So we allowed for that. This worked great until…

[email protected]
People started using other TLD’s. Now we change validation to be the email had letters, an @ sign, letters, and then ended with .[com,net,org,gov,edu]. This worked great until…

[email protected]
People started using numbers in their emails. So we allowed numbers in the emails. This worked great until…

[email protected]
People started using special characters in their email (think periods, plus signs, etc). So we allowed for those. This worked great until…

[email protected]
All kinds of TLD’s became a thing. The wild west of TLD’s. So then we just said anything after the dot. This worked great until…

[email protected]
Some very nerdy people used IP addresses instead of domains. So we allowed IP addresses. This worked great until…

me@0:0:0:0:0:0:0:1
Some really nerdy people started using IPV6 instead of IPv4. So we allowed for that.

Don’t even get me started on validating if something is a valid IP address.

NLog Setup

Every time I make a file new project I need to add logging – how many times have I spent time figuring out what needs to go where, how to format the error email, and how to log uncaught errors(oh noes!). Too many times. So here is me condensing adding NLog to a web project quickly and easily:

Install NLog.config(and with it NLog) on your web project.

Add these to NLog.config:

<targets>
 <target name="Mail" xsi:type="Mail" html="true" subject="Error Received" layout="${longdate} LEVEL=${uppercase:${level}}, LOCATION=${callsite:className=true:includeSourcePath=true:methodName=true}, MESSAGE=${message}${newline} EXCEPTION=${exception:format=tostring,StackTrace}${newline" addNewLines="true" replaceNewlineWithBrTagInHtml="true" to="[email protected]" from="[email protected]" useSystemNetMailSettings="true" >
 </targets>
<rules>
 <logger name="*" level="Error" writeTo="Mail" >
 <logger name="*" level="Fatal" writeTo="Mail" >
 </rules>

Add this to global.asax.cs

protected void Application_Error()
 {
 Exception lastException = Server.GetLastError();
 Logger logger = LogManager.GetCurrentClassLogger();
 logger.Fatal(lastException);
 }

There is some feature interaction with how you handle your errors, to get things working you may need to temporarily change customErrors mode to Off in web.config(but this should never go to production!)

Exceptions Deserve to be Handled

Some code smell I came upon today! Exceptions should always be handled in some way, even if just logging it and continuing on(the next person troubleshooting a problem will thank you). Also, exceptions should be exceptional – they are slow and break up code flow; avoid using them for normal circumstances, like bad user input.


try
{
   //do something
}
catch (Exception e) { }

Development, Testing, and Quality Assurance

How important is it that your software runs correctly and to spec? For most software it is of the utmost importance. One of the Joel Test 12 is “Do you fix bugs before writing new code?”. Smart development, testing, and QA help prevent bugs in software.

Fixing Code Before Production and After

Fixing code before it goes to production will save you time. I have had bugs that would have taken 30 seconds to fix before going to production that I spent more than a week on fixing after it went to production because it messed up data in another system.

Ways to Prevent Bugs

One of the big things in the programming industry in recent years has been unit testing(and integration testing, TDD, BDD, etc.). Testing is good! It helps find bugs before they are a problem and helps developers make changes in important parts of the code base and have more confidence that they aren’t causing problems in other parts.

If I had a dollar for every time I was asked if I’m writing unit tests why QA is needed, I would definitely have a few dollars. Very simply, QA finds bugs that unit testing does not. Unit and integration testing catch many things, but even though I keep making better software, users will always find a better way to break software.

When Building An Interface, Think About the Customer

When building an interface/class, a software engineer should think about how other software engineers are his target customer. This means that the interface should be designed with the needs and preferences of other software engineers in mind.

Here are some reasons why software engineers should consider other software engineers as their target customer when building an interface:

  1. Efficiency in Workflow: Other software engineers will have similar workflows to the developer who is building the interface. The interface should be designed to facilitate efficient workflows, using well-established patterns and conventions to streamline the process.
  2. Customization and Flexibility: Other software engineers may require customization or flexibility in the interface to cater to their individual needs. The interface should be designed to allow for customization and flexibility, using modular components and flexible layouts.
  3. Clarity and Consistency: Other software engineers may be working on different parts of the project or may be working on the same codebase at a different time. The interface should be designed to ensure clarity and consistency, using clear labeling and navigation, and consistent design patterns.
  4. Consideration for Technical Competence: Other software engineers may have different levels of technical competence, and the interface should be designed to cater to this variance. This can be achieved by using clear error messages, detailed documentation, and helpful tooltips.

In conclusion, when building an interface, software engineers should think about other software engineers as their target customer. By designing interfaces that cater to the needs and preferences of other software engineers, developers can create interfaces that are efficient, flexible, clear, consistent, and considerate of technical competence. This can help to ensure that the interface is well-received and widely used by other software engineers, leading to more effective and efficient software development.