Program Correctness & Efficiency
Program Correctness & Efficiency
Briana Morrison
Outline
Categories of program errors
Throwing an exception:
What it means
How to do it
Why you should catch exceptions
A variety of testing strategies
Debugging techniques Big-O notation
What it is
How to use it to analyze an algorithm’s
efficiency
2
Program Defects and “Bugs”
An efficient program is worthless if it breaks
or produces a wrong answer
Defects often appear in software after it is
delivered
Testing cannot prove the absence of defects
It can be difficult to test a software product
completely in the environment in which it is
used
Debugging: removing defects
3
Major Categories of Defects
Logic Errors
4
Syntax Errors
Syntax errors: grammatical mistakes in a
program
The compiler detects syntax errors
You must correct them to compile successfully
Some common syntax errors include:
Omitting or misplacing braces, parentheses, etc.
Misplaced end-of-comment
Typographical errors (in names, etc.)
Misplaced keywords
5
Semantic Errors
Semantic errors: may obey grammar, but violate
other rules of the language
The compiler detects semantic errors
You must correct them to compile successfully
Some common semantic errors include:
Performing an incorrect operation on a primitive type
value
Invoking a member function not defined
Not declaring a variable before using it
Providing multiple declarations of a variable
Failure to include a library header
6
Run-time Errors or Exceptions
Run-time errors
Occur during program execution (run-
time!)
Occur when the C++ run-time library
detects an operation that it knows to be
incorrect
Cause program to halt execution
Examples of run-time errors include
Division by zero
Array index out of bounds
Null pointer reference 7
Run-time Errors or Exceptions
(continued)
Run-Time Error Cause
Division by zero Integer division by zero.
Array index out of bounds Attempt to access an array with an index value that is greater
than the array length (not detected by C+ + ).
Null pointer reference. Attempt to dereference a pointer whose value is NULL.
8
Logic Errors
A logic error is programmer mistake in
the design of a class or method, or
the implementation of an algorithm
Most logic errors
Are not syntax or semantic errors: get by
the compiler
Do not cause run-time errors
Thus they are difficult to find
Sometimes found through testing
Sometimes found by users
9
Ways to Indicate an Error
Return a special value
Use a bool return value to indicate
success or failure.
Set a global variable.
Print an error message.
Print an error message and exit the
program.
Put an input or output stream in a fail
state.
Throw an exception 10
Example – using a special
return value
The function get_element_of_x will return
numeric_limits<int>::min() if the index is not
valid.
It’s use is illustrated as follows:
int value = get_element_of_x(i);
if (value > numeric_limits<int>::min()) {
// Do something with value
. . .
} else {
// Recover from the error
. . .
}
// Continue normal processing 11
Throwing an Exception
Using special return values to indicate
errors can lead to complicated logic.
The error detection/recovery logic is
intermixed with the normal processing.
Using exceptions allows separation of
the error detection/recovery logic from
the normal processing logic.
12
Example using a throw
/** Gets the value in the element of array x with subscript index.
@param index The subscript of the element to be retrieved
@return The value stored at x[index]
@throws A std::out_of_range exception if index is not in range.
*/
int get_element_of_x(int index) {
if (index < 0 || index >= X_SIZE) {
throw std::out_of_range(
"In get_element_of_x, "
"the value of index is out of range");
}
return x[index];
}
13
Uncaught exceptions
If there is no exception handler, the program
execution is aborted.
The message depends on the compiler and
operating system.
The g++ compiler issues the message
Aborted
The Microsoft .NET C++ compiler issues the
message
This application has requested the Runtime to
terminate it in an unusual way.
Please contact the application's support team
for more information.
14
Catching and Handling Exceptions
A try block encloses functions that may throw
an exception.
One or more catch blocks (exception
handlers) follow the try block.
try {
val = get_element_of_x(10);
}
catch (std::out_of_range& ex) {
std::cerr << "Out_of_range exception\n";
std::cerr << ex.what() << std::endl;
std::abort();
}
15
Standard Exceptions
Sta nda rd Exception Reas on Thrown Thrown by
bad_alloc Memory not available. The new operator.
bad_cast Attempt to cast a reference that is not of The dynamic_cast operator.
the target type.
bad_typeid Attempt to obtain the typeid of a null The typeid operator.
pointer or the default typeid object.
domain_error Function not defined for the input Not thrown by the C+ + standard
value. library.
invalid_argument Invalid function argument. The bitset constructor.
length_error Attempt to create a string or vector that The string and vector classes.
is larger than the maximum allowed size.
out_of_range Index that is larger than size() The at operator in the string,
vector, and deque class.
ios_base::failure An error flag is being set that matches Input/ output stream objects after an
one set by an earlier call to the erroneous input/ output operaton.
exceptions function.
16
Testing Programs
A program with
No syntax/semantic errors, and
No run-time errors,
conditions
Verifying the results
Program compiles
Integration testing:
The interactions among units
19
Some Types of Testing
Black-box testing:
Tests item based only on its interfaces
White-box testing:
Tests with knowledge of internal
structure
20
Preparing to Test
Develop test plan early, in the design phase
How to test the software
When to do the tests
Who will do the testing
What test data to use
Early test plan allows testing during design &
coding
Good programmer practices defensive
programming
Includes code to detect unexpected or invalid
data
21
Testing Tips for Program Systems
Program systems contain collections of
classes, each with several methods
A method specification should document
Input parameters
Expected results
Carefully document:
Each method parameter
Each class attribute (instance and static variable)
As you write the code!
22
Testing Tips for Program Systems
Trace execution by displaying method
name as you enter a method:
#define TRACING
...
int compute_weight (...) {
#ifdef TRACING
cerr << "Entering
compute_weight\n";
#endif
. . .
}
23
Testing Tips for Program Systems
Display values of all input parameters
on entry:
int compute_weight (float volume,
float density) {
#ifdef TRACING
cerr << "Entering computeWeight";
cerr << "volume = " << volume;
cerr << "density = " << density <<
'\n';
#endif
...
}
24
Testing Tips for Program Systems
Display values of any class data
members (instance and static) accessed
by the method
Display values of all method outputs at
point of return from a method
Plan for testing as you write each
module,
Not after the fact!
25
Developing Test Data
Specify test data during analysis and design
For each level of testing: unit, integration, and system
Black-box testing: unit inputs outputs
Check all expected inputs
Check unanticipated data
White-box testing: exercise all code paths
Different tests to make each if test (etc.) true and false
Called coverage
26
Developing Test Data (2)
Helpful to do both black- and white-box
testing
Black-box tests can be developed early
since they have to do with the unit
specification
White-box tests are developed with
detailed design or implementation: need
code structure
27
Testing Boundary Conditions
Exercise all paths for
Hand-tracing in a structured walkthrough
28
The Big Idea
How will we compare one data structure with
another?
How do I know when to use a Red-Black Tree
versus a Hash Table?
29
Efficiency of Algorithms
By comparing the efficiency of algorithms, we have
one basis of comparison that can help us determine
the best technique to use in a particular situation.
Travel
- by foot
- by car
- by train
- by airplane
30
Efficiency of Algorithms
Question: How can we characterize the
performance of an algorithm ...
Without regard to a specific computer?
Without regard to a specific language?
Over a wide range of inputs?
Desire: Function that describes execution time
in terms of input size
Other measures might be memory needed, etc.
31
Analysis of Algorithms
The measure of the amount of work an
algorithm performs (time)
or
the space requirements of an implementation
(space)
Complexity
Order of magnitude
is a function of the number of data items.
32
Running Time
Most algorithms transform best case
Running Time
80
with the input size.
60
Average case time is often
difficult to determine. 40
running time. 0
1000 2000 3000 4000
Easier to analyze Input Size
Crucial to applications such as
games, finance and robotics
33
The “Order” of Performance:
(Big) O
Basic idea:
1. Ignore constant factor: computer and language
implementation details affect that: go for
fundamental rate of increase with problem size.
2. Consider fastest growing term: Eventually, for
large problems, it will dominate.
Value: Compares fundamental performance
difference of algorithms
Caveat: For smaller problems, big-O worse
performer may actually do better
34
Big-O notation
Big-O notation provides a machine independent
meanssort,
For the selection for determining
the number the efficiency is
of comparisons
of an =Algorithm.
T(n) n2/2 - n/2.
2
n n
T(n)
2 2
35
Big-O Notation
Algorithm A requires time proportional to a function
F(N) given a reasonable implementation and
computer.
big-o notation is then written as O(n) where n is
proportional to the number of data items
You can ignore constants
O(5n2) is O(n2)
You can ignore low-order terms
O(n3 +n2 + n) is O(n3)
36
T(n) = O(f(n))
T(n) = time for algorithm on input size n
f(n) = a simpler function that grows at
about the same rate
37
Growth Rates
1E+30
Growth rates of 1E+28 Cubic
functions: 1E+26
1E+24 Quadratic
Linear n 1E+22
Linear
1E+20
Quadratic n2 1E+18
Cubic n3
T (n )
1E+16
1E+14
1E+12
In a log-log chart, 1E+10
1E+8
the slope of the line 1E+6
corresponds to the 1E+4
1E+2
growth rate of the 1E+0
function 1E+0 1E+2 1E+4 1E+6 1E+8 1E+10
n
38
Constant Factors
1E+26
The growth rate is 1E+24 Quadratic
Quadratic
not affected by 1E+22
1E+20 Linear
constant factors or 1E+18 Linear
lower-order terms 1E+16
1E+14
Examples T (n ) 1E+12
1E+10
102n 105 is a linear 1E+8
function 1E+6
105n2 108n is a 1E+4
quadratic function 1E+2
1E+0
1E+0 1E+2 1E+4 1E+6 1E+8 1E+10
n
39
Growth Rates
Common Growth Rates
Big-O Name
O(1) Constant
O(log n) Logarithmic
O(n) Linear
O(n log n) Log-Linear
O(n2) Quadric
O(n3) Cubic
O(2n) Exponential
O(n!) Factorial
40
Growth Rates
Constant O(1) print first item
Linear O(n) print list of items
Polynomial O(n2) print table of items
Logarithmic O(log n) binary search
Exponential O(2n) listing all the subsets of
a set
Factorial O(n!) traveling salesperson
problem
41
Efficiency of Algorithms
(continued)
42
Chessboard Puzzle
Payment scheme #1: $1 on first square, $2 on
second, $3 on third, ..., $64 on 64th.
Which is best?
43
Chessboard Puzzle Analyzed
Payment scheme #1: Total = $1+$2+$3+...+$64
= $6465/2 = $1755
44
Exponential Algorithms
n log2n n log2n n2 n3 2n
2 1 2 4 8 4
4 2 8 16 64 16
8 3 24 64 512 256
16 4 64 256 4096 65536
32 5 160 1024 32768 4294967296
128 7 896 16384 2097152 3.4 x 1038
1024 10 10240 1048576 1073741824 1.8 x 10308
65536 16 1048576 4294967296 2.8 x 1014 Forget it!
45