Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Developing with Performance in Mind

DZone's Guide to

Developing with Performance in Mind

While testing is important, building your next project while keeping performance in mind makes subsequent testing that much more efficient.

· Performance Zone ·
Free Resource

Container Monitoring and Management eBook: Read about the new realities of containerization.

When developers are faced with building a solution, they focus on "making it work." What they sometimes forget is the importance of application performance. Whether it's web, desktop or mobile device-based programming, your users want an application that responds quickly. They don't want a desktop application that hangs or a web application that takes too long to load. When you approach a development project, it's just as important to focus on performance in addition to creating a bug-free application.

Performance and Revenue

In development, businesses talk in terms of revenue. Prioritization of projects, application goals, and customer engagement are all tied with revenue. Performance metrics also tie into overall revenue for a business. Just a four-second delay in load times results in a 25% increased bounce rate on a website. This means that if the business is making, for instance, $2 million a year in revenue with 10,000 customers, poor performance could be costing them $500,000 each year.

Desktop development may not rely on web page load times, but a hanging, buggy application results in uninstalls. Installation and downloads are the two metrics that mobile device and desktop application developers watch. When we say a "hanging" app, it's one that interferes with desktop performance and overwhelms CPU and memory resources. For a user, this means that other applications and the computer or mobile device itself runs slowly. The user can identify the culprit on their machine and eventually remove it. For a business, it means the loss of a customer and revenue.

When you approach a development project, it's just as important to focus on performance in addition to creating a bug-free application.

Coding for Performance

One of the traditional statements in coding is that you only need to learn one language (preferably a C-style language), and you know them all. Learning syntax for different languages is easy. Understanding best practices for engineering and building entire platforms on any language is the difficult part.

Even if you don't know a specific language, most of them work with the same coding structures — loops, variables, functions, pointers, data types, and arrays are all examples of common structures in any language. Some languages handle memory resources and storage differently, but most of the basic performance-enhancing techniques in one language will carry over to another. For this reason, the languages used in the following ex- amples can be applied to your own coding language of choice.

Stringbuilder vs. String for Concatenation

The StringBuilder class and object type is available in C# and Java. It's common for a developer to work with the basic string data type and build a string for output based on concatenation procedures. StringBuilder is built for better string concatenation performance and should be used in place of traditional strings when you want to manipulate values.

Learning syntax for different languages is easy. Understanding best practices for engineering and building entire platforms on any language is the difficult part.

C#

public class BadStringConcatenation {
    static void Main() {
        string myString = "";
        for (int i = 0; i < 100000; i++) {
            myString += " Hello ";
        }
        Console.WriteLine("String value: {0}", myString);
    }
}


Above is an example of using the string data type for concatenation. The performance-killing issue with this code is that the compiler doesn't just keep adding "Hello" to the myStringvariable. Instead, it takes a copy of the string, recreates the new string, and then adds the new value to myString again. The compiler has to create an entirely new string with eachiteration. Since we have a 100,000-iteration loop, this function isn't optimal.

Instead, you should use StringBuilder.

public class GoodStringConcatenation {
    static void Main() {
        StringBuilder myString = new StringBuilder();
        for (int i = 0; i < 100000; i++) {
            myString.Append(" Hello ");
        }
        Console.WriteLine("String value: {0}", myString.ToString());
    }
}

With StringBuilder, you no longer take copies of large string variables during each iteration. Instead, you only copy the appended string and add it to the existing one. Application speed increases, and your users aren't waiting several seconds for calculations.

Use Primitive Data Types Instead of Objects

The previous example made a case for using the StringBuilder object, but with most procedures you want to stick with primitive data types. We'll use the Java language to illustrate why. Java has eight defined primitive types - int, double, boolean, byte, short, long, char, and float. When you can use these primitive data types, use them instead of their object data type counterpart.

The following code has two statements. The first one uses the primitive Java data type int. The second one uses the object Integer.

Java

int myPrimitiveInt = 100;
Integer myObjectNumber = new Integer(100);

Both of these statements create an integer variable that contains the value 100. The first statement is preferred due to performance. The performance costs in the second statement stem from the way the compiler stores both of these values. Primitive data types are stored in a section of memory called the stack. Objects such as the Integer object in the second statement are stored in the stack as a reference to a second section of memory called the heap.

Image title

Source: Orange Coast College

When the compiler needs to retrieve the primitive int variable value, it grabs it directly from the stack. However, when the compiler retrieves the second Integer object value, it grabs a reference to the heap. It then needs to go to the memory instance where the object is allocated and perform a lookup for the value. This might seem like a subtle difference, but it plays a role in performance. When you are doing low-level programming such as gaming software, these small changes make a difference in the user's experience and your application's speed.

Precision Costs You Performance and Memory

At a high level, you might think rounding at the 10th decimal point is not a big deal, but some applications require precision, particularly financial, engineering, or science applications. A fraction of a milligram can affect someone's health. Rounding to the wrong number could affect the structural integrity of a building. Precision and rounding are critical to these types of application. However, precision comes at a price: performance.

The basic rule for developers is use as much precision as you need, but only use it if you need it. If you don't need a 128-bit floating point number (28-29 decimal points), then don't use it. You waste memory and CPU resources to calculate problems.

In the above code, foreach is used to iterate through the list. A foreach loop uses an enumerator to "walk" through each value in the list. Enumerators contain a Current, MoveNext, and Reset class. Each time an iteration is made, the Enumerator must make a call to Current and MoveNext to keep track of the current and next value in the list. These calls add up when you have a large list to work through.

The basic rule for developers is use as much precision as you need, but only use it if you need it. If you don't need a 128-bit floating point number (28-29 decimal points), then don't use it. You waste memory and CPU resources to calculate problems.

A float or double data type should be used when precision isn't important. A float is only 32 bits, and a double is 64 bits. Float is notorious for inaccurate results, so only use floats when you are exactly sure of what type of precision you need. This leaves double as the default for most programmers, but always consider memory usage before you determine which one to use.

Use FOR Instead of FOREACH

Similar to using StringBuilder instead of string for concatenation, using for instead of foreach  also has a performance benefit. This usually becomes an issue when you have a generic list and need to iterate over each value. 

C#

public class ListIteration {
    static void Main() {
        List < Customer > customers = new List < Customer >
            foreach(var customer in customers) {
                Console.WriteLine("Customer name: {0}",
                    customer.Name);
            }
    }
}

In the above code, foreach is used to iterate through the list. A foreach loop uses an enumerator to "walk" through each value in the list. Enumerators contain a CurrentMoveNext, and Reset  class. Each time an iteration is made, the Enumerator must make a call to Current  and MoveNext  to keep track of the current and next value in the list. These calls add up when you have a large list to work through.

public class ListIteration

{
    static void Main() {
        List < Customer > customers = new List < Customer >
            for (i = 0; i < customers.Count; i++) {
                Console.WriteLine("Customer name: {0}", customer[i].Name);
            }
    }
}

We changed the foreach  loop to a for , and if you test the two methods you'll see that this for loop executes much faster. With a for loop, only one get_Item  method is called, which reduces the time it takes to execute this function.

Wrap Up

Take these examples and try them out yourself. You'll notice a huge difference in execution time. Although small amounts of data might not seem like a big difference, when you are coding for businesses that rely on heavy data transactions, the difference makes a huge difference in productivity and revenue. 


This article is featured in the new DZone Guide to Performance: Testing and Tuning. Get your free copy for more insightful articles, industry statistics, and more! 

Take the Chaos Out of Container Monitoring. View the webcast on-demand!

Topics:
performance ,ui ,concatenation ,performance development ,stringbuilder

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}