Data Structures and Algorithms Lecture Notes

2 March 2011 Performance Estimation in Practice


Outline

What Does This Algorithm Do?

int find(int a[], int x)

  for (int i = 0; i < |a|; i++)
    if a[i] == x
      return i

  return -1

What Does This Algorithm Do?

int find(int a[], int x)
  l = 0
  r = |a|
  while l < r
    m = (l + r)/2
    if a[m] == x
      return m
    if a[m] <= x
      l = m + 1
    else
      r = m
  return -1

Assumptions

Let's Estimate!

Basic Statements

  for (int i = 0; i < |a|; i++) : O(1)
    if a[i] == x : O(1)
      return i : O(1)

  return -1 : O(1)

Choice Statements

  for (O(1); O(1); O(1)))
    if O(1) : O(1)
      O(1)

  O(1)

Iteration Statements

  for (O(1); O(1); O(1))) : O(1)
    O(1)

  O(1)

Statement Sequences

O(n)

O(1)

Second Program

  l = 0 : O(1)
  r = |a| : O(1)
  while l < r : O(1)
    m = (l + r)/2 : O(1)
    if a[m] == x : O(1)
      return m : O(1)
    if a[m]  x : O(1)
      l = m + 1 : O(1)
    else
      r = m : O(1)
  return -1 : O(1)

Conditional Statements

O(1)
O(1)
while O(1)
  O(1)
  if O(1)
    O(1)
  if O(1)
    O(1)
  else
    O(1)
O(1)

O(1)
O(1)
while O(1)
  O(1)
  if O(1) : O(1)
    O(1)
  if O(1)
    O(1)
  else
    O(1)
O(1)

O(1)
O(1)
while O(1)
  O(1)
  O(1)
  if O(1) : O(1)
    O(1)
  else
    O(1)
O(1)

Compound Statements

O(1)
O(1)
while O(1)
  O(1) : O(1)
  O(1)
  O(1)
O(1)

Looping

Finishing Up

O(1)
O(1)
O(log n)
O(1)

Static Arrays vs. Dynamic Data

Dynamic Arrays

Implementation

class sequence
  Object data []
  int next-data

  append(T e)

    if next-data  data.length()
      Object new-data [] = 
        new Object [data.length() + 1]
      for i = 0 to data.length() - 1
        new-data[i] = data[i]
      data = new-data

    data[next-data++] = e

Appending Costs

Worst-Case Analysis

if next-data  data.length() : O(1)
  Object new-data [] = new 
    Object [data.length() + 1] : O(1)?/O(n)
  for i = 0 to data.length() - 1 : O(1)
    new-data[i] = data[i] : O(1)
  data = new-data : O(1)
data[next-data++] = e : O(1)

if O(1)
  O(1) or O(n)
  for O(1) : O(n)
    O(1)
  O(1) or O(n)
O(1)

Worst-Case Appending

if O(1)
  O(1) or O(n)
  O(n)
  O(1) or O(n)
O(1)

if O(1)
  O(n)
O(1)

O(n)
O(1)

O(n)

So?

Sloppy Analysis

Less Sloppy Analysis

Better Behavior

Amortized Sequences

class sequence
  Object data []
  int next-data
  unsigned a = 50

  append(T e)

    if next-data  data.length()
      Object new-data [] = 
        new Object [data.length() + a]
      for i = 0 to data.length() - 1
        new-data[i] = data[i]
      data = new-data

    data[next-data++] = e

Worst-Case Analysis

 if next-data  data.length() : O(1)
  Object new-data [] = new 
    Object [data.length() + a] : O(n)
  for i = 0 to data.length() - 1 : O(1)
    new-data[i] = data[i] : O(1)
  data = new-data : O(1)
data[next-data++] = e : O(1) 

Amortization Effects

Less Sloppy Analysis.

Less Sloppy Analysis..

Does It?

amortization in effect

amortization in effect

Asymptotically Better Behavior

Multiplicative Sequences

class sequence

  Object data []
  int next-data

  append(T e)

    if next-data  data.length()
      Object new-data [] = 
        new Object [data.length()*2]
      for i = 0 to data.length() - 1
        new-data[i] = data[i]
      data = new-data

    data[next-data++] = e

Analysis.

Analysis..

Does It?

Summary


This page last modified on 2010 March 2.

Creative
    Commons License