Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Algorithms (2006)

.pdf
Скачиваний:
255
Добавлен:
17.08.2013
Размер:
9.67 Mб
Скачать

Chapter 19

The main() method delegates much of the work to methods that will be shown later. Note that after the words are loaded from the input stream, the reverseAll() method is called to — you guessed it — reverse all the words. The list of reversed words is then sorted using a NaturalComparator that treats them like normal strings. The strings in the resulting sorted list are then reversed again and printed out.

Next is the loadWords() method. It is unchanged from the FileSortingHelper class shown previously:

private static List loadWords() throws IOException { List result = new ArrayList();

BufferedReader reader = new BufferedReader(new InputStreamReader (System.in));

try {

String word;

while ((word = reader.readLine()) != null) { result.add(word);

}

} finally { reader.close();

}

return result;

}

The reverse() method, shown here, was all that was salvaged out of the now redundant ReverseStringComparator that you created earlier in the chapter:

private static String reverse(String s) { StringBuffer result = new StringBuffer();

for (int i = 0; i < s.length(); i++) { result.append(s.charAt(s.length() - 1 - i));

}

return result.toString();

}

The reverseAll() method simply iterates over the List provided to it, treating each element as a String that is reversed and placed back into the List:

private static void reverseAll(List words) { for (int i = 0; i < words.size(); ++i) {

words.set(i, reverse((String) words.get(i)));

}

}

The printAll() method is also a simple list iteration routine to print out the elements in the List supplied to it:

484

Pragmatic Optimization

private static void printAll(List stringList) { Iterator iterator = stringList.iterator(); iterator.first();

while (!iterator.isDone()) {

String word = (String) iterator.current(); System.out.println(word); iterator.next();

}

}

How It Works

It’s now time to try running our optimized version of the sample application. The following command will use the JMP to profile our OptimizedFileSortingHelper:

java -Xrunjmp com.wrox.algorithms.sorting.OptimizedFileSortingHelper <words.txt >sorted.txt

The JMP output for this run is shown in Figure 19-6.

Figure 19-6: JMP output from the OptimizedFileSortingHelper.

485

Chapter 19

Take a closer look at the JMP Methods window, shown in Figure 19-7, to determine whether you have eliminated the 50 seconds of effort you spent doing all that string reversing.

Figure 19-7: The JMP Methods window for the OptimizedFileSortingHelper.

You can see that there is no sign of the reverse() method in this list of bottleneck methods. Note also that the biggest contributor is only taking four seconds anyway! This is looking like a huge improvement.

Now take a closer look at the JMP Objects window, shown in Figure 19-8, to determine whether your prediction of reduced garbage collection panned out as you hoped.

Figure 19-8: The JMP Objects window for the OptimizedFileSortingHelper.

There is also a dramatic change here. Look at the #GC column for the top line, which is the total number of objects of all classes that were garbage collected during the program execution. It is less than 80,000, whereas previously it was over 2 million! Also note that the number of String objects that were garbage collected was around 20,000, which fits with our expectation of twice reversing each of the 10,000 input words. It is very important to verify that the numbers make sense to you in the context of the change you have made, so make sure you check each time you make a change and re-profile your application.

You have done two rounds of optimization for our sample application, dramatically reducing the time taken by the bottleneck execution methods. The final thing you need to do is leave the profiling and go back to normal execution to see how well it runs. Recall that this program originally took over a minute to run on our machine. Run without the JMP command-line switch:

java com.wrox.algorithms.sorting.OptimizedFileSortingHelper <words.txt >sorted.txt

486

Pragmatic Optimization

How It Works

The program now runs in under two seconds! That’s around 50 times faster than our first version. This is quite typical of the real-world experience we have had optimizing Java code. The important thing is that we didn’t have to give any thought to performance while writing the code, other than to carefully select an algorithm with the right characteristics for our needs. Well-designed code that is clear and simple lends itself to later optimization very well. For example, the fact that you were able to unplug implementations of the List and Comparator interfaces in the example program was key to achieving the performance you wanted.

Summar y

In this chapter, you learned that . . .

Optimization is an important aspect of software development, but not as important as a good understanding of algorithms.

Profiling is a technique to gather hard facts about the runtime behavior of your Java code.

The Java Virtual Machine supports profiling with a simple command-line argument syntax.

The free Java Memory Profiler provides a graphical view of the memory usage of your application, allowing you to quickly find the problem areas that you need to address.

You can make an example of a slow-running program run 50 times faster with a targeted and methodical approach to optimization.

487

A

Fur ther Reading

It is hoped that this book has inspired you to delve further into the world of algorithms. Of course, we also hope you’ll take with you some of the design patterns and ideas from test-driven development as well! Here are some books on these topics that you might want to peruse next time you’re in the bookstore. There is also a wealth of resources on the Internet that you can easily find by typing a few keywords into your favorite search engine, so we’ll leave that to you.

Algorithms in Java, Third Edition, Parts 1–4: Fundamentals, Data Structures, Sorting, Searching, by Robert Sedgewick. Addison Wesley, 2002.

Design Patterns, by Erich Gamma et al. Addison-Wesley, 1995.

File Structures, by Michael Folk and Bill Zoellick. Addison-Wesley, 1991.

Introduction to Algorithms, Second Edition, by Thomas H. Cormen et al. The MIT Press, 2001.

Java Performance Tuning, Second Edition, by Jack Shirazi. O’Reilly Associates, 2003.

JUnit in Action, by Vincent Massol with Ted Husted. Manning, 2004.

Test-Driven Development: By Example, by Kent Beck. Addison-Wesley, 2002.

Test-Driven Development: A Practical Guide, by David Astels. Prentice Hall PTR, 2003.

The Art of Computer Programming, Volume 1: Fundamental Algorithms (Second Edition), by Donald E. Knuth. Addison-Wesley, 1973.

The Art of Computer Programming, Volume 3: Sorting and Searching (Second Edition), by Donald E. Knuth. Addison-Wesley, 1998.

B

Resources

Apache Jakarta Commons: http://jakarta.apache.org/commons

Java Memory Profiler home page: www.khelekore.org/jmp/

JUnit: www.junit.org

National Institute of Standards and Technology: www.nist.gov

Project Gutenberg: www.gutenberg.org

Unicode home page: www.unicode.org

University of Southern Denmark Department of Mathematics and Computer Science:

http://imada.sdu.dk

University of Calgary Department of Computer Science: www.cpsc.ucalgary.ca

Wikipedia: www.wikipedia.org

Word Lists: http://wordlist.sourceforge.net/

C

Bibliography

[Astels, 2003] Astels, David. Test-Driven Development: A Practical Guide. Prentice Hall PTR, 2003.

[Beck, 2000] Beck, Kent. Extreme Programming Explained. Boston: Addison-Wesley, 2000.

[Beck, 2002] Beck, Kent. Test-Driven Development: By Example. Addison Wesley Longman, 2002.

[Bloch, 2001] Bloch, Joshua. Effective Java. Addison-Wesley, 2001.

[Cormen, 2001] Cormen, Thomas H., et al. Introduction to Algorithms, Second Edition. The MIT Press, 2001.

[Crispin, 2002] Crispin, Lisa, and Tip House. Testing Extreme Programming. Addison Wesley, 2002.

[Fowler, 1999] Fowler, Martin. Refactoring. Addison-Wesley, 1999.

[Gamma, 1995] Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns. Addison-Wesley, 1995.

[Hunt, 2000] Hunt, Andy, and Dave Thomas. The Pragmatic Programmer. Addison-Wesley, 2000.

[Knuth, 1973] Knuth, Donald E. Fundamental Algorithms, Volume 1 of The Art of Computer Programming, Second Edition. Addison-Wesley, 1973.

[Knuth, 1998] Knuth, Donald E. Sorting and Searching, Volume 3 of The Art of Computer Programming, Second Edition. Addison-Wesley, 1998.

[Massol, 2004] Massol, Vincent. JUnit in Action. Manning, 2004.

[Sanchez, 2003] Sánchez-Crespo Dalmau, Daniel. Core Techniques and Algorithms in Game Programming. New Riders Publishing, 2003.

[Sedgewick, 2002] Sedgewick, Robert. Algorithms in Java, Third Edition, Parts 1–4: Fundamentals, Data Structures, Sorting, Searching. Addison Wesley, 2002.