Last time, we separated numerical functions into orders of growth.
For figuring out about how fast things grow, we can:
- Take only the highest degree term.
- Ignore any coefficient.
We can classify our functions by that highest degree term.
- f(x) = 1
- f(x) = log2(x)
- f(x) = x
- f(x) = x*log2(x)
- f(x) = x^2
- f(x) = x^3
- f(x) = 2^x
Today, we’ll look at how this applies to comparing algorithms on computers.
Let’s start with a sorted ArrayList of N integers:
[3, 11, 41, 92, 278, 531, ...], length = N
Let’s consider a simple function that determines if a given number appears in the list.
    static boolean listContains(List<Integer> xs, int yy) {
        for (int ii = 0; ii < xs.size(); ++ii) {
            int xx = xs.get(ii);
            if (xx == yy) {
                return true;
            }
        }
        return false;
    }
How many operations does this take?
- 
Calling a method takes some operations, but we’ll ignore that for the moment. 
- 
The loop will happen several times, once per item in the list. - We already said the list is length N, so the loop runs N times.
 
- 
int ii = 0 // once 
- 
ii < xs.size() // N times 
- 
++ii // N times 
- 
int xx = xs.get(ii) // N times 
- 
if (xx == yy) // N times 
- 
return true // At most once 
- 
return false // At most once 
- 
So that’s 4 things that happen N times + 3 things that happen once. 
- 
But some of the things might be many operations: - ii < xs.size()? How many ops is xs.size() for an ArrayList?
- Is “<” and the method call two separate things?
 
- xs.get()? Again, for an ArrayList.
 
- ii < xs.size()? How many ops is xs.size() for an ArrayList?
- 
It ends up being about ops(n) = 4n + 3, or O(n). 
Let’s consider some more:
- 
Finding the smallest value in a sorted list. 
- 
Determining if any two items sum to 100. - Random list?
- Sorted list?
 
- 
Finding the median value in the list. 
- 
Finding the median value… with a LinkedList. 
- 
Binary Search on an ArrayList. 
- 
What if we have two lists? Let’s consider a function that determines if there is some pair of items, one from xs and one from ys, that sum to 100. 
Wait a second: We want time!
Let’s consider that listContains method again.
- We really want time. How does that relate to “operations”?
- How long does “++ii” take?
- This one’s reasonably simple.
- The int value ii will be stored in a CPU register, and increment is one machine instruction. It takes one clock cycle.
- There are some complexities, but running on one core of 3 GHz CPU we can reasonably expect to be able to do about 3 billion integer increments in a second.
 
- How long does “xs.get(ii)” take?
- Again, the integer value ii lives in a register.
- The xs variable will be in a register too, but that’s not the list, that’s the address of the ArrayList object.
- So we’ve got to fetch that object from memory.
- But that’s still not the list. The items are in an array which is referenced from a field of the object.
- So we’ve got to fetch that from memory.
 
- How long does a memory fetch take?
- If we need to go out to main memory, it could take 80ns or 240 clock cycles.
- But there’s cache. A best case cache hit might only take 4 clock cycles (or less than 2ns).
- So the first call of xs.get(ii) might take 160ns, the second one might take
 
