Software Quality - Princeton High School

advertisement
Software Quality
We want our software to be of high quality. But what does that mean? As is often
the case, there are a variety of quality characteristics to consider.
Quality
Characteristics Description
Correctness
Reliability
Robustness
Usability
Maintainability
Reusability
Portability
Efficiency
The degree to which software adheres to its
specific requirements.
The frequency and criticality of software
failure.
The degree to which erroneous situations are
handled gracefully.
The ease with which users can learn and
execute tasks within the software.
The ease with which changes can be made
to the software.
The ease with which software components
can be reused in the development of other
software systems.
The ease with which software components
can be used in multiple computer
environments.
The degree to which the software fulfills its
purpose without wasting resources.
THE EFFICENT USE OF RESOURCES
One of the most important resources is CPU time. The efficiency of an algorithm
we use to accomplish a particular task is a major factor that determines how fast
a program executes. Although we can analyze an algorithm relative to the
amount of memory it uses, CPU time is usually the more interesting issue.
Let’s look at the issues related to algorithm analysis and the groundwork for
using analysis techniques with an example: washing dishes by hand. If we
assume that washing a dish takes 30 seconds and drying a dish takes an
additional 30 seconds, then we can see quite easily that it would take a minute to
wash and dry n dishes. This computation could be expressed as follows:
Time (n dishes) = n  ( 30 seconds wash time + 30 seconds dry time )
= 60n seconds
On the other hand, suppose we were careless while washing the dishes and
splashed too much water around. Suppose each time we washed a dish, we had
to dry not only that dish but also all of the dishes we had washed before that one.
It would still take 30 seconds to wash each dish, but now it would take 30
seconds to dry the last dish (once), 2  30 or 60 seconds to dry the second-to-last
dish (twice), 3  30 or 90 seconds to dry the third-to-last dish (three times), and so
on. This computation could be expressed as follows:
Time (n dishes) = n  ( 30 seconds wash time) +

n
i 1
(i  30)
( n  1)
2
2
= 15n + 45n seconds
= 30n + 30n
If there were 30 dishes to wash, the first approach would take 30 minutes,
whereas the second (careless) approach would take 247.5 minutes. The more
dishes we wash the worse that discrepancy becomes.
One might assume that, with the advances in the speed of processors and
availability of large amounts of inexpensive memory, algorithm analysis would no
longer be necessary. However, nothing could be farther from the truth. Processor
speed and memory cannot make up for the differences in efficiency of
algorithms.
For every algorithm we want to analyze, we need to define the size of the
problem. For our dishwashing example, the size of the problem is the number of
dishes to be washed and dried. We also must determine the value that
represents efficient use of time or space. For time considerations, we often pick
and appropriate processing step that we’d like to minimize, such as our goal to
minimize the number of times a dish has to be washed and dried. The overall
amount of time spent at the task is directly related to how many times we have to
perform that task. The algorithm’s efficiency can be defined in terms of the
problem size and the processing step.





Consider an algorithm that sorts a list of numbers into increasing order. One
natural way to express the size f the problem would be the number of values
to be sorted.
The processing step we are trying to optimize could be expressed as the
number of comparisons we have to make for the algorithm to put the values
in order.
The more comparisons we make, the more CPU time is used.
A growth function shows the relationship between the size of the problem
(n) and the value we hope to optimize.
This function represents the time complexity or space complexity of the
algorithm.
The growth function for our second dishwashing algorithm is
t( n ) = 15n2 + 45n
However, is not typically necessary to know the exact growth function for an
algorithm. Instead, we are mainly interested in the asymptotic complexity of an
algorithm. That is, we want to focus on the general nature of the function as n
increases. This characteristic is based on the dominant term of the expression –
the term that increases most quickly as n increases. As n gets very large, the
value of the dishwashing growth function approaches n because the term grows
much faster than the n term. The constants and the secondary term quickly
become irrelevant as n increases.
The asymptotic complexity is called the order of the algorithm. Thus, our
dishwashing algorithm is said to have order n time complexity, written O(n 2).
This is referred to as Big O( ) or Bog-Oh notation.
Growth Function
t(n)=17
t(n)=20n -5
t(n)=12n log n + 100n
t(n)=3n2 + 5n – 2
t(n)=2n + 18n2 + 3n
Order
O(1)
O(n)
O(n log )
O(n2)
O(2n)
Questions
1. What is the difference between the growth function of an algorithm and the
order of that algorithm?
2. Why does speeding up the CPU not necessarily speed up the process by
the same amount?
Exercises
1. What is the order of the following growth functions?
a. 10n2 + 100n + 1000
b. 10n3 – 7
c. 2n + 100n3
d. n2 log n
2. Arrange the growth functions of the previous exercise in ascending order
of efficiency for n=10 and again for n=1,000,000.
3. Write the code necessary to find the largest element in an unsorted array
of integers. What is the time complexity of this algorithm?
4. Determine the growth function and order of the following code fragment:
for (int count=0; count < n; count++)
{
for (int count2=0; count2 < n; count2=count2  2)
{
/* some sequence of O(1) steps */
}
}
Download