Micro-Tuning Step-by-Step

Micro-Tuning Step-by-Step

After the Baseline

We now have three routes we can follow in proceeding with the micro-tuning:



  • Consider the inefficiencies highlighted by the baseline measurements.
  • Analyze the algorithm to determine if there are generic inefficiencies that we can improve.
  • Profile the method to determine where the bottlenecks are, if there are any.

These three routes are generic; micro-tuning generally has these options, though any one option may become unavailable when the code becomes more efficient. Usually, some of the options are easier to proceed with than others, but for this article it is instructive to look at all three.

Dataset 3

The baseline measurement shows that using Dataset 3 required a much longer time to execute than using the other two datasets. The major difference in this dataset is the existence of strings that do not hold valid numbers. We can easily follow the logic for this case: the method tries to create an Integer object by parsing the string using the Integer constructor. In cases where the string is not a number, the constructor throws a NumberFormatException. This is caught in our catch block, and false is returned. So it seems that this procedure is extremely expensive.

In fact, it is fairly well known that creating an exception is an expensive procedure. The actual cost comes from filling out the stack trace that the exception holds, and even though we never care about the stack trace in this method, we cannot avoid its cost. We can, however, avoid the exception completely by checking that we have a valid number before creating the Integer. This is simply done by checking all of the characters to make sure they are all digits:

for (int i = 0; i < testInteger.length(); i++)

  if (!Character.isDigit(testInteger.charAt(i)))

    return false;

Note that negative numbers will return false using this loop, but that is acceptable, since the method in any case always returns false when passed a negative number. Re-running our test with this code added to the beginning of the method produces the results listed in Table 2.

Table 2: After adding the looped digit test

  Dataset 1 Dataset 2 Dataset 3
Baseline 100% 84.1% 540.0%
With looped digit test 114.8% 66.1% 51.4%

So we've improved the test using Dataset 3 to be faster than the tests using both the other datasets, in line with what we expected. The test using Dataset 2 is also improved, which I didn't expect.

The Algorithm

Let's look at the algorithm for any inefficiencies. The algorithm has one obvious redundancy: we check that the integer is greater than 10 and, if it is, we subsequently check that it is greater than or equal to 2.

(theInteger.intValue() > 10) && ((theInteger.intValue() >= 2)

Clearly, we can dispense with the second test completely. If the first (>10) test fails, then the following (>=2) will not be executed, since we are using the shortcut Boolean AND operator (&&), which only executes its right-hand side if the left-hand side is true. If the "greater than 10" test succeeds, then we know definitely that the "greater than or equal to 2" test will succeed. Are there further inefficiencies? Let's go line-by-line. For convenience, here's the full function again.

1 public boolean checkInteger(String testInteger)

2 {

3   try

4   {

5     Integer theInteger = new Integer(testInteger);//fails if not  a number

6     return

7       (theInteger.toString() != "") && //not empty

8       (theInteger.intValue() > 10) && //greater than ten

9       ((theInteger.intValue() >= 2) && 

10           (theInteger.intValue() <= 100000)) && //2>=X<=100000

11     (theInteger.toString().charAt(0) == '3'); //first digit is 3               

12  }

13  catch (NumberFormatException err)

14  {

15    return false;

16  }     

17}

First we create an Integer (5). Then we test for an empty string (7). But on checking the Integer class, an empty string is an invalid number for the Integer constructor, so if we do have an empty string, this test will never be executed. If an empty string is passed to the method, the Integer constructor will throw an exception and the catch block will be immediately activated. So we should either eliminate the empty string test, or move it before the Integer creation. It's highly likely that a simple empty string test is faster than the Integer creation procedure, so we should move the test to before the Integer creation. (Note that the test was, in any case, incorrect in using the identity operator != rather than the equals() method, and I'll correct that here.)

Moving on, the "greater than 10" test (8) is necessary, and we've already eliminated the "greater than or equal to 2" test (9). The "less than or equal to 100000" (10) is necessary, and the test for the first digit being 3 (11) is necessary.

If the first digit is 3, however, the smallest possible valid number is 30 (since the number must be greater than 10); thus the "greater than 10" test should become a "greater than 29" test. Similarly, the largest number possible up to 100000, that starts with a 3, is 39999, so the "less than or equal to 100000" test should become "less than 40000."

Finally, the test for the first digit being 3 is surely simpler to execute than creating the Integer. To create the Integer, the minimum that would need to be executed would be to check that every character is a digit. So it makes sense to move the "first digit being 3" test to before the creation of the Integer.

public boolean checkInteger(String testInteger)

{

  try

  {

    if (testInteger.equals("")) return false;

    if (testInteger.charAt(0) != '3') return false;

    Integer theInteger = new Integer(testInteger);//fails if not  a number

    return

      (theInteger.intValue() > 29) &&

      (theInteger.intValue() <= 40000);

  }

  catch (NumberFormatException err)

  {

    return false;

  }     

}

Re-running our test using this code produces the results listed in Table 3.

Table 3: After restructuring the algorithm

  Dataset 1 Dataset 2 Dataset 3
Baseline 100% 84.1% 540.0%
Restructured algorithm 46.6% 39.9% 29.8%

Prev  [1] [2] [3] [4] Next

Close    To Top
  • Prev Article-Java:
  • Next Article-Java:
  • Now: Tutorial for Web and Software Design > Java > Java Basic > Java Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction