📄 ch20.htm
字号:
<HTML>
<HEAD>
<TITLE>Chapter 20 -- Optimizing Java Code for Games</TITLE>
<META>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 20</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Optimizing Java Code for Games</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>
<UL>
<LI><A HREF="#WhatIsCodeOptimization" >What Is Code Optimization?</A>
<UL>
<LI><A HREF="#Maintainability" >Maintainability</A>
<LI><A HREF="#Size" >Size</A>
<LI><A HREF="#Speed" >Speed</A>
</UL>
<LI><A HREF="#OptimizingwiththeJDKCompiler" >Optimizing with the JDK Compiler</A>
<LI><A HREF="#CostsofCommonOperations" >Costs of Common Operations</A>
<LI><A HREF="#IsolatingProblemCode" >Isolating Problem Code</A>
<LI><A HREF="#OptimizationTechniques" >Optimization Techniques</A>
<UL>
<LI><A HREF="#RethinkAlgorithms" >Rethink Algorithms</A>
<LI><A HREF="#UseNativeMethods" >Use Native Methods</A>
<LI><A HREF="#UseInlineMethods" >Use Inline Methods</A>
<LI><A HREF="#ReplaceSlowJavaAPIClassesandMethod" >Replace Slow Java API Classes and Methods</A>
<LI><A HREF="#UseLookUpTables" >Use Look-Up Tables</A>
<LI><A HREF="#EliminateUnnecessaryEvaluations" >Eliminate Unnecessary Evaluations</A>
<LI><A HREF="#EliminateCommonSubexpressions" >Eliminate Common Subexpressions</A>
<LI><A HREF="#ExpandLoops" >Expand Loops</A>
</UL>
<LI><A HREF="#Summary" >Summary</A>
<LI><A HREF="#QA" >Q&A</A>
<LI><A HREF="#Workshop" >Workshop </A>
<UL>
<LI><A HREF="#Quiz" >Quiz</A>
<LI><A HREF="#Exercises" >Exercises</A>
</UL>
</UL>
<HR>
<P>
Execution speed has always had a unique importance to game developers.
More so than any other area of software, games typically must
squeeze every ounce of performance out of the host system. This
is distressing news for those of us writing games in Java, simply
because Java is so removed from the specifics of the host system
that it's extremely difficult to cut corners while coding. However,
even though you can't get down and dirty with the hardware, you
can still optimize Java code in various ways to improve performance
in your games.
<P>
Today's lesson deals with Java code optimization and how it can
be used to speed up Java games. You'll learn various optimization
techniques that will help you become a more efficient Java programmer.
To really understand how these optimizations help, you have to
go under the hood of Java, so roll up your sleeves and prepare
to get a little dirty.
<P>
As you go through today's lesson, keep in mind that it's one of
the last lessons in the book for a very good reason: Any thoughts
of optimizing your code should occur near the end of the development
cycle. In other words, focus on getting your game up and running,
and then focus your attention on looking for ways to optimize.
<P>
The following topics are covered in today's lesson:
<UL>
<LI>What is code optimization?
<LI>Understanding the JDK compiler
<LI>Costs of common operations
<LI>Isolating problem code
<LI>Optimization techniques
</UL>
<H2><A NAME="WhatIsCodeOptimization"><B><FONT SIZE=5 COLOR=#FF0000>What
Is Code Optimization?</FONT></B></A></H2>
<P>
Code optimization is the process of modifying working code to
a more optimal state based on a particular goal. The fact that
optimization takes place on working code is an important point;
always perform optimizations on code <I>after</I> you get the
code working. The type of optimization performed is dependent
on the desired goal; code optimization can be divided into three
distinct types, which are based on the needs of the developer:
<UL>
<LI>Maintainability
<LI>Size
<LI>Speed
</UL>
<H3><A NAME="Maintainability"><B>Maintainability</B></A></H3>
<P>
Maintainability optimization is performed to help make code more
manageable in the future. This type of optimization is usually
geared toward the structure and organization of code, rather than
modifications of the algorithms used in the code. In general,
maintainability optimization involves a programmer studying the
code at large and making changes to help other programmers understand
and modify the code in the future.
<P>
If you haven't guessed, maintainability optimization doesn't rank
very high on the list of important optimizations used by game
developers. It's still important to organize your code and enforce
some structure, but just don't let maintainability optimization
become an overriding concern.
<H3><A NAME="Size"><B>Size</B></A></H3>
<P>
Another popular optimization is size optimization, which involves
making changes to code that result in a smaller executable class
file. The cornerstone of size optimization is code reuse, which
comes in the form of inheritance for Java classes. Fortunately,
good OOP design strategies naturally favor size optimization,
so you will rarely need to go out of your way to perform this
type of optimization. For example, it's just good design practice
to put code that is reused a few times in a method. In this way,
most size optimizations naturally take place during the initial
code development.
<P>
Although not entirely crucial, size optimization can't be completely
ignored in regard to Java game programming. This is because the
size of your compiled Java classes will directly impact the amount
of time it takes your game to load and initially execute. If,
however, you leverage as much of the standard Java API code as
possible and reuse code by deriving from other classes, you're
probably doing enough for the cause of reducing class size.
<H3><A NAME="Speed"><B>Speed</B></A></H3>
<P>
And now, introducing the real subject of today's lesson: speed
optimization. Speed optimization is without a doubt the most important
aspect of game development after the game is up and running correctly.
Speed optimization includes all the techniques and tricks used
to speed up the execution of code. Considering the performance
problems inherent in Java, speed optimization takes on an even
more important role in Java than in other languages such as C
and C++. Because the Java compiler has the last word on how code
is generated, most speed optimizations will be performed with
the compiler in mind.
<P>
The rest of today's lesson focuses on issues of speed optimization
and how to get the best performance out of your Java code. At
times, you will sacrifice the other areas of optimization for
the sake of speed. In most cases, this sacrifice is entirely acceptable,
even expected, because the organization of the code and size of
the executable classes won't matter much if your game is too slow
to play.
<H2><A NAME="OptimizingwiththeJDKCompiler"><B><FONT SIZE=5 COLOR=#FF0000>Optimizing
with the JDK Compiler</FONT></B></A></H2>
<P>
All optimizations begin and end with the Java compiler. If you
don't understand the compiler, you're largely guessing at which
optimizations will have a positive effect on your code. So let's
take a look at the JDK compiler and see what role it plays in
turning out speedy Java bytecodes.
<P>
A <I>bytecode</I> is a Java term referring to the intermediate
processor-independent code generated by the Java compiler. Bytecode
executables (classes) are interpreted by the Java runtime system.
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Third-party Java compilers are turning up and will continue to turn up that outclass the JDK compiler in regard to speed optimization. Nevertheless, the JDK compiler is the standard Java compiler and currently the most reliable.</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<P>
The JDK compiler (<TT><FONT FACE="Courier">javac</FONT></TT>)
includes a switch for generating optimized Java bytecode executables:
<TT><FONT FACE="Courier">-O</FONT></TT>. In release 1.0 of the
JDK, this switch results in only two optimizations taking place:
inline methods and exclusion of line numbers. The first of these
optimizations is the only one that affects the speed of the executable
bytecode; final, static, and private methods are inlined by the
compiler, resulting in less method call overhead.
<P>
<I>Method inlining</I> is the process of replacing each call to
a method with the actual method code. Inlining can often increase
the size of the resulting class file, but it can help improve
performance.
<P>
The second optimization performed by the JDK compiler results
in the exclusion of line number information from the executable
class file. This is a size optimization and does nothing in terms
of helping speed up the code.
<P>
As you can see, the JDK compiler does little for you in regard
to optimization. This basically means that you need to plan on
doing a lot of optimization by hand. A future release of the JDK
should (I hope) improve this situation, but you can't afford to
stand around waiting for miracles-you've got games to write!
<H2><A NAME="CostsofCommonOperations"><B><FONT SIZE=5 COLOR=#FF0000>Costs
of Common Operations</FONT></B></A></H2>
<P>
Now that you understand what the JDK compiler does (or doesn't
do) for you in regard to optimization, it's time to focus on the
Java runtime system. By examining the runtime system, you can
get an idea of how fast certain types of code run and make smarter
decisions about the way you write Java code. What do I mean by
examining the runtime system? Well, I mean running different types
of code and timing each type to see how the speeds match up. This
operation gives you a very realistic look at how code differs
in terms of execution speed and consequently gives you a place
to start making appropriate code optimizations.
<P>
The speed of an operation is often referred to as the <I>cost</I>
of the operation. Code optimization can almost be likened to accounting,
in which you try to keep from blowing a performance budget with
your code costs. As if optimization weren't tedious enough as
it is, I had to make a reference to accounting! Anyway, Jonathan
Hardwick performed a very neat analysis on the cost of common
Java operations on various systems, the results of which I've
included in Tables 20.1 through 20.3. These tables contain approximate
times in microseconds for common Java operations. Incidentally,
the systems used to perform the cost analysis were a Sun Sparcstation
5 running Solaris, an AMD 486 DX4-120 running Windows 95, and
an AMD 486 DX4-120 running Linux 1.2.13.
<P>
In terms of speed optimization, <I>cost</I> refers to the speed
required to perform an operation.<BR>
<BLOCKQUOTE>
<B><CENTER>Table 20.1. The costs of Java variable accesses.</B></CENTER>
</BLOCKQUOTE>
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><I>Description</I></TD><TD WIDTH=129><I>Operation</I>
</TD><TD WIDTH=65><CENTER><I>Solaris</I></TD><TD WIDTH=93><CENTER><I>486 Win95</I>
</TD><TD WIDTH=87><CENTER><I>486 Linux</I></TD></TR>
<TR><TD WIDTH=129>Method variable assignment</TD><TD WIDTH=129><TT><FONT FACE="Courier">i = 1;</FONT></TT>
</TD><TD WIDTH=65><CENTER>0.4</TD><TD WIDTH=93><CENTER>0.3</TD><TD WIDTH=87><CENTER>0.5
</TD></TR>
<TR><TD WIDTH=129>Instance variable assignment</TD><TD WIDTH=129><TT><FONT FACE="Courier">this.i = 1;</FONT></TT>
</TD><TD WIDTH=65><CENTER>2.4</TD><TD WIDTH=93><CENTER>0.7</TD><TD WIDTH=87><CENTER>0.9
</TD></TR>
<TR><TD WIDTH=129>Array element assignment</TD><TD WIDTH=129><TT><FONT FACE="Courier">a[0] = 1;</FONT></TT>
</TD><TD WIDTH=65><CENTER>1.1</TD><TD WIDTH=93><CENTER>1.0</TD><TD WIDTH=87><CENTER>1.3
</TD></TR>
</TABLE></CENTER>
<P>
<BLOCKQUOTE>
<B><CENTER>Table 20.2. The costs of increment with Java data types.</B></CENTER>
</BLOCKQUOTE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -