Writing Efficient Programs

Free download. Book file PDF easily for everyone and every device. You can download and read online Writing Efficient Programs file PDF Book only if you are registered here. And also you can download or read online all Book PDF file that related with Writing Efficient Programs book. Happy reading Writing Efficient Programs Bookeveryone. Download file Free Book PDF Writing Efficient Programs at Complete PDF Library. This Book have some digital formats such us :paperbook, ebook, kindle, epub, fb2 and another formats. Here is The CompletePDF Book Library. It's free to register here to get Book file PDF Writing Efficient Programs Pocket Guide.

This situation can lead to a misuse of some features and a disuse of others that may be either more elegant or more efficient, or both, than those that are used. It may even be possible, as noted by Hoare , to use unknown features accidentally, with bizarre results.

See a Problem?

How can user-defined operator overloading harm the readability of a program? Because The compiler does not come to know how to make precision of this operator. What is one example of a lack of orthogonality in the design of C? C has two kinds of structured data types, arrays and records structs , records can be returned from functions but arrays cannot. A member of a structure can be any data type except void or a structure of the same type.

Assignment 1

An array element can be any data type except void or a function. What language used orthogonality as a primary design criterion? Problem Sets 6. Java uses a right brace to mark the end of all compound statements. What are the arguments for and against this design? The argument for using the right brace to close all compounds is simplicity—a right brace always terminates a compound.

This optimization can bring large benefits, especially in a superscalar CPU like the R However, loop unrolling is a touchy, error-prone operation to carry out by hand, and the resulting code is hard to read and to maintain. Fortunately, the 7. You can control the amount of unrolling either with a compiler option or loop-by-loop with directives.

The compiler takes care of the niggling details and the bookkeeping involved in handling end-of-loop, while the source code remains readable. A benefit of compiler-controlled loop unrolling is that the compiler applies the optimizations of common subexpression elimination, constant propagation, code motion out of loops, and function call inlining both before and after unrolling the loop.

The optimizations work together for a synergistic effect. The software-pipelining optimization rearranging the order of the generated machine instructions in order to maximize use of the R execution units also becomes more effective when it has a longer loop body to work on. When a large cost of an inner loop is devoted to trivial assignments other than maintenance of loop indices , the assignments can be reduced by duplicating the loop body and renaming the variables in the second copy.

As with simple loop unrolling, this important optimization is well-handled by the compiler. Leave your code simple and readable and let the compiler do this. A fast loop should have no unconditional branches. An unconditional branch at the end of a loop can be handled by "rotating" the loop to put a conditional branch at the bottom. This optimization might be needed in assembly-language code, but no modern compiler should generate code for a loop with the test at the top and an unconditional branch at the bottom.

If two nearby loops operate on the same set of elements, combine their operational parts and use only one set of loop-control operations. Example: convert. This technique can produce important benefits in the Origin because, first, the contents of array b are only passed through the cache once, and second, the instructions to load each element of b from the second loop are eliminated.

However, it is not necessary for you to perform this optimization manually. The 7. The compilers can also perform the following optimizations:. Each of these changes, if done manually, complicates the source code with many temporary variables and insanely complicated loop control. In general, write loop code in the simplest, most portable and maintainable fashion, and then let the compiler tangle it behind the scenes.

In a conditional expression, replace a costly expression with an algebraically equivalent expression that is cheaper to evaluate. Any such replacements that require insight are worth doing. Do not spend time replacing simple manifest expressions with constants; the compiler is good at that, and good at recognizing common subexpressions.

When a monotone function of several variables is to be tested for a threshold value, break off the test as soon as the result is known. Short-circuit evaluation of a Boolean expression is a well-known case handled automatically by the compiler. Bentley gives a more interesting example. Given a function to find the point in a list that is nearest to a given point:.

This function as it stands short-circuits the distance computation for purposes of comparing two distances, it is sufficient to compare the sum of squares and skip doing the square root. However, in many cases the X-distance alone is enough to eliminate a point, which avoids the need for the second multiply and an addition.

Logical tests should be arranged such that cheap tests precede expensive ones, and so that ones most likely to succeed precede ones more likely to fail. In the absence of other information, the SGI compilers assume that the then part of an if is more likely than the else , so it is good practice to put the most likely code in the then part. It is possible to run the program under speedshop experiment type ideal , producing a file of exact execution counts.

This file can be filtered through prof format -feedback and the resulting file can be fed back into the next compilation. The compiler will take branch execution counts from the feedback file, and create an instruction schedule that reflects the exact probabilities of each branch. This is a convenient feature that can have good results on a poorly-written program. However, the compiler does not take into account the cost of a test that involves a function call, or a test that can touch an unused cache line or page.

Your insight is still needed to order tests so as to avoid expensive operations when possible. A logical function over a small, finite domain can be replaced by a table lookup.

source link

/Writing efficient programs pdf at master · cjl/ · GitHub

Examples include using a table to classify characters in lexical classes, and implementing an interpreter using a branch table indexed by instruction code. When the table is small and frequently-used, this technique is almost always helpful. However, when the table is sparse, or much larger than the executable code that it replaces, the effect of the table on the cache could swamp the benefits. Assignment to a Boolean variable and its later test can be replaced by an if statement on the Boolean value. Generalizing, assignment to any control variable over a small, finite domain can be replaced by a case statement on the value that would have been assigned.

Application of this rule saves three things: declaration of a variable to hold a control value; assignment into the variable; and fetching from the variable when the value is tested. The rule says that instead, you should modify the code so the control value is used to direct execution as soon as the value is calculated.

In some cases you have to duplicate code in order to apply the rule. When the sole use of a local variable is to hold a value between its expression and a following test, the compiler at -O2 and higher is quite capable of eliminating the variable and using only a register temp. Hence the only time you should distort your program's logic to apply this rule is when the assignment is separated from its use by many statements, or by a non-inlined procedure call, A procedure call usually makes the compiler spill register values to memory.

The run time of a set of procedures that nonrecursively call themselves can often be reduced by rewriting the procedures inline and binding what were passed arguments. This technique is extremely useful, but difficult to apply to an existing program and still leave the program readable and maintainable.

Program optimization

Given that, it is best to write the program in a plain, naive way, not fretting about frequent calls to small procedures, and to let the compiler inline the small procedures. Although inlining eliminates the instruction overhead of a function call, it inflates the size of the object code. At a certain level of inlining, the effect of the inflated, low-density code on cache and virtual memory wastes as much time as it saves.

6.7 Writing Efficient Code

Keep in mind the maintenance implications of inlining procedures in code you will distribute to other users. A library procedure that has been inlined even once can never be field-replaced. In an Evaluate statement, the When clauses continue to be evaluated until an End-evaluate or a Break statement is encountered. If you have an Evaluate statement with a number of When clauses, and you only expect one of them to match, put a Break statement following the likely clause. Otherwise, all the subsequent When clauses are evaluated.

Your program is still correct, but it is inefficient at runtime, particularly if you have a large number of When clauses, and the Evaluate statement is in a loop.

How to Write Memory-Efficient Java Code

Govern your state. One of the key features in PeopleSoft Pure Internet Architecture is that the application server is stateless. When required, the state of your session is bundled up and exchanged between the application server and the web server. For example, on a user interaction, the whole state, including your PeopleCode state, has to be serialized to the web server. Then, once the interaction has completed, that state is deserialized in the application server so that your application can continue. To improve efficiency:.

Watch the size of PeopleCode objects that you create strings, arrays, and so on to make sure they are only as big as you need them to be. For user interactions, you might be able to change the logic of your program to minimize the state. For example if you are building up a large string a couple of megabytes and then performing a user interaction, you might be able to change your program logic to build the string after the interaction.

For secondary pages that are infrequently accessed but retrieve lots of data, consider setting No Auto Select in the Application Designer for the grids and scroll areas on the secondary page, to prevent loading the data the secondary page when the page buffers are initially built. Then add the necessary Select method to the Activate event for the secondary page to load the data into the grid or scroll area.

Isolate common expressions.

  • Stocks and Bonds, Profits and Losses: A Quick Look at Financial Markets;
  • Clifford Algebra to Geometric Calculus: A Unified Language for Mathematics and Physics;
  • Copyright:.
  • Special order items.

For example, the PeopleCode compiler does not do common subexpression analysis. So, sometimes, if you have a complicated bit of PeopleCode that is used often, you can isolate the common expression yourself.

This isolation can make your code look cleaner and make your code faster, especially if it is in a loop. In this example, notice how the common subexpression is broken out:. The compiler has to evaluate each occurrence of the expression, even though it would only execute it once.