Introduction:
There are many different ways to write a program to perform a given task. For example, in Java there are at least three fundamentally different ways to write a program: Unstructured, Procedural and Object Oriented. In an unstructured program, all of the code would be placed in the main method and no method calls would be used. For example, the following unstructured program sums up all of the numbers from 1 to 1000:
Another approach would be to use a procedural programming approach and break the program into subroutines implemented as static methods. Using a procedural programming approach the program for summing the numbers from 1 to 1000 might appear as:
The third approach would be to use an object oriented approach, identifying the objects and instance methods necessary to complete the program. With an object oriented approach our example program might appear as:
These increasingly complex programming paradigms (unstructured, procedural and object oriented) bring with them the ability to deal effectively with larger and larger programs. However, along with this increased effectiveness for large programs comes increased overhead that can decrease performance. In fact, you have probably been told that method calls incur additional overhead that makes them slower than including the same code in-line. For example, the statement x=y*y; will execute more quickly than x=Math.pow(y,2.0); because the overhead associated with the method call can be eliminated. Similarly, the AllInMain program above will execute more quickly than the StaticMethod program.
In this project you will measure and compare the time required to call Getting Started:
static and instance methods in Java (i.e. Java's method call overhead).
To get started you will need a tool that allows you measure how much time each part of a program takes to execute. You will then be able to use this tool, and some calculations, to determine how much overhead is incurred when calling methods in Java. Fortunately, the Java Virtual Machine (JVM) provides a profiler which is just such a tool. The profiler in the JVM will keep track of the total time it takes a program to execute and what percentage of that total time is spent in each method in the program.
As an example of how to use the JVM profiler we'll use the following variant of the AllInMain program from above:
The MainTest program still computes the sum of all of the numbers from 1 to 1000. However, it repeats this operation 100,000 times. The reason that it is repeated 100,000 times is so that the time used by the main method represents a significant portion of the total time required for the program to execute. If the sum were only performed once then other operations such as initializing the JVM and loading the class take more time than the code in which we are interested. By ensuring that the code in which we are interested dominates the total execution time we will obtain more accurate results.
To use the JVM profiler, you compile the program normally and use a command line argument to the JVM to ask it to perform profiling. For example, to profile the MainTest program you would use the command:
This command will run the MainTest program and record the profiling data in a file named java.hprof.txt. Note, that you may see several lines of output that say "HPROF ERROR". These are due to glitches in the profiler and will not affect your results and can safely be ignored. The java.hprof.txt file contains a lot of information. The information that you will be interested in for this project appears near the end of the file and will look similar to the following:
In the first line above, Collecting the Data:
total = 12400 indicates that the MainTest program took a total of 12400 milliseconds (i.e. 12.400 seconds) to execute. The following lines provided profiling information about each method called (directly or indirectly) by the MainTest program. The rank column indicates which methods used the most time, with lower ranks indicating the methods that used the most time. In the table above, the main method in the MainTest class has rank 1, indicating that it used the most time. The self column indicates the percentage of the total time that was used by each method. For example, the main method used 98.31% of the total time, while the charAt method in the java.lang.String class used 0.08% of the total time. The accum column maintains a running total of the percentage of total time used by all of the methods with lower rank. For example, the last line in the table above indicates that the methods with rank 1 through 7 used 98.79% of the total time.
You should begin by collecting data on the amount of time the MainTest program spends in the main method. However, to ensure accurate results you should adjust the number of iterations in the for (int j=0...) loop so that the main method uses at least 90% of the total time before collection your data. Also, be sure to use good experimental technique by collecting and averaging the data from at least 20 trials.
After collecting data for MainTest you will need to conduct additional experiments to collect data that will allow you to calculate the overhead of static and instance method calls. Specifically, you need to find the time it takes to make a single static method call and the time it takes to make a single instance method call. The examples in the introduction should give you some good ideas on how to get started.
IMPORTANT: As you begin to design the programs, experiments and calculations that you will use the single most important thing you need to do is to ensure that you are isolating the method call overhead. In other words, make sure that the values you are finding represent only the time required for the method calls and nothing else.
The Write ups:
There will be three written documents associated with this project. The first will be a project proposal written collectively by each group. The second and third documents will be a rough draft and final draft of a scientific paper describing the project. The rough and final drafts must be written individually.
Project Proposal
Your goal in the project proposal is to communicate exactly what you plan to do and how you plan to do it. Your proposal should begin by very briefly stating the goal of the project and then outlining how the goal will be accomplished. In particular you must describe any programs you plan to use and include their source code. You must also discuss precisely what data you will collect and what calculations you will perform to determine the method calling overheads. Note, it is not expected that you have collected any data at this point, only that you have thought very carefully about the data that you will need and how you are going to collect it.
Your proposal should be no more than two pages in length excluding code. You should write your proposal as if the target audience were another member of this class. Thus, the language and terminology that you use should be clear to your peers. In evaluating your proposal I will be looking almost exclusively at how well the experiment you describe isolates the method calling overhead.
Rough and Final Drafts
Each individual will turn in both a rough draft and a final draft. The rough and final drafts should be 5-7 pages. These drafts will take the form of a scientific paper with the following sections:
Introduction:
In the introduction you will state the question that you have investigated and provide some motivation for why it is an interesting question.
Background:
Your background section should serve to provide an uninitiated reader with enough information to understand the question that you are investigating and what makes it interesting. While the introduction stated the question and why it is interesting this section, as the name suggests, provides more background and a more detailed discussion.
In this paper, your background section will need to define and discuss unstructured, procedural and object oriented programming and the applications and trade-offs of each of them. You may find websites and introductory computer science textbooks, available in the library, helpful in improving your understanding of these programming paradigms. Be sure to reference any sources that you use.
Methods & Results:
Your goal in the methods and results section is to describe in detail the experiments that you used to measure the method call overhead and to present your results in an understandable form. You will need to discuss the programs that you used, the data that you collected, how you collected that data and the calculations that you performed. Based on what you say in this section, it should be possible for someone who reads your paper to precisely repeat your experiments. Note that to precisely repeat your experiment the reader will need to know what hardware, operating system, compiler etc. that you used. You should be sure to choose the most appropriate technique (i.e. text, tables, charts, graphs etc..) for presenting your results. You might also include a brief interpretation of each of the results in this section or depending on your writing style you may delay such a discussion until the conclusions.
Conclusions:
In your conclusions you should very briefly recap what you have done. You should explicitly state and discuss the answer to the question you set out to investigate as well as any implications of the answer that you found. You also need to be sure to identify any limitations of your results and suggest techniques for addressing those limitations.
Your paper should be formatted using the same guidelines as are used for departmental honors theses. You can find these guidelines and some sample pages in the Honors Thesis Style Guide. For this paper the relevant information will be contained in the sections on "Reference and Citation Format" and "Thesis Formatting". You should follow the formatting guidelines for the Thesis except that you do not need to include a signature page, acknowledgments or a table of contents. Also, your paper will not be divided into chapters, so you should just use section headings for the introduction, background, methods and results, and conclusions sections.
Bonus:
In addition to working with static and instance methods, also analyze final instance methods. This will require that you expand your background section to discuss the meaning and effect of the final modifier. Your conclusions will also have to thoroughly explain the results in light of the use of the final modifier. If you complete the bonus your score on the final draft will be increased by up to 10% depending on the quality of your work on the bonus material.