# Laboratory Session: Observation and Analysis

Description: In the laboratory, you will be recording data on the running time of algorithms and determining whether those data correspond to your understanding of the running time of those algorithms. In order to complete the lab, you will need to determine a way to generate a sequence of timings for each of the various algorithms.

Purpose: In this lab, you will gain experience doing experimental run-time analysis of programs. Hopefully, this will also give you better understanding of asymptotic analysis.

Note: This laboratory is much more open-ended than the step-by-step laboratories that you are used to. I expect that by this point, you are ready for less step-by-step instructions.

## Preparation

I've created a set of utilities that support various operations on arrays of integers, including searching and sorting. You should scan the documentation for that library. You may also want to read the source code for those algorithms.

In order to determine the running time of algorithms, we need a mechanism for getting the current time. Java provides such a function as part of `java.lang.System`. The method is called `currentTimeMillis` and is called as `System.currentTimeMillis()`.

I've written a sample program that times a sorting routine for a given size input. This program is also reproduced at the end of this lab. Copy and compile this program so that you can determine the running time of that routine. Note that you can use
`% example SortTimer.java`
to make a copy of the code.

## Exercise

Write a program or sequence of programs that provide you with a reasonable set of data points that will help you determine the approximate running time (in big-O notation) of each of the following algorithms:

One possibility is to print out a series of data points that you graph by hand. Another is to build something that graphs the points.

You may base your program on my sample program or build your own from scratch.

Using these data, estimate the running time of each method in Big-O notation.

You should design your programs in such a way that it is not necessary to recompile in order to gather multiple data points for the same algorithm.

## Reflection

Here are some questions you might have asked yourself while doing this lab.

What size arrays should I use?

Clearly, smaller arrays will be faster. At the same time, they may be too fast to gain meaningful results (the size may be smaller than n0). Larger arrays will be more meaningful, but we don't want them to be so large that the program takes "forever" to run. I chose to run tests for 1,2,3,...,10,20,30,...100,200,...,1000.

Did you verify that the algorithms worked?

If I hadn't provided you with the source code for my program, it would be important to ensure that the algorithms worked correctly. Otherwise, the test is meaningless. Even though I provided the code, you may not be sure that it's right unless you do a formal analysis. Since most of us aren't up to such analyses, it would be useful to check. One particular problem I noted in some of your solutions was that you ran binary search on an unsorted array.

How many tests are enough for one size array?

We've already noted that the running time may differ for a single size array because the algorithm depends on the exact inputs. Often, sorting an already sorted array is much quicker than sorting a completely random array. To ensure that your values are reasonable, you should have done each test multiple times and reported average, maximum, and minimum.

What did you search for?

Linear search works much better if you search for something at the beginning of the list. Binary search works much better if you search for the exact middle element. It would be reasonable to search for a variety of elements and report average, maximum, and minimum. One of you suggested that searching for something not in the array would be a useful metric.

What results did you get?

None yet.

## Sample Code

```
import rebelsky.util.IntegerArrayAlgorithms;
import rebelsky.io.SimpleOutput;

/**
* A simple timer for one of the sorting algorithms provided by
* rebelsky.util.IntegerArrayAlgorithms.
*
* @author Samuel A. Rebelsky
* @version 1.0 of February 1998
*/
public class SortTimer
{
/**
* Sort 1000 things and report on the time it took.  Crash and
* burn when one of the methods I use crashes and burns.
*/
public static void main(String[] args)
throws Exception
{
// The size of the arrays we'll be creating.
int size = 500;
// The array we'll be working with.
int[] arr;
// A sorted version of that array.
int[] sorted;
// How to print output.
SimpleOutput out = new SimpleOutput();
// The time (wall clock) before the sorting starts.
long start;
// The time (wall clock) after sorting ends.
long finish;

// Generate a "random" array of the appropriate size
arr = IntegerArrayAlgorithms.random(size);
// Get the current time (in milliseconds since some weird date).
start = System.currentTimeMillis();
// Sort!
sorted = IntegerArrayAlgorithms.bubbleSort(arr);
// Get the current time
finish = System.currentTimeMillis();
// The elapsed time is the difference between the two times.
System.out.println("Sorting " + size + " elements took "
+ (finish-start) + " milliseconds");
} // main
} // SortTimer

```

History

• Created February 1998 for CSC152 98S.
• Updated February 1999 for CSC152 99S.

Disclaimer Often, these pages were created "on the fly" with little, if any, proofreading. Any or all of the information on the pages may be incorrect. Please contact me if you notice errors.