Download presentation
Presentation is loading. Please wait.
1
CS 144 Advanced C++ Programming May 9 Class Meeting
Department of Computer Engineering San Jose State University Spring 2019 Instructor: Ron Mak
2
Final Exam Friday, May 17 Similar in format to the midterm.
7:15 – 9:30 AM in MH 233 Similar in format to the midterm. Canvas + lockdown browser Multiple-choice + short-answer questions Covers the entire semester with emphasis on the second half. Tip: Be sure to understand the programming assignments.
3
Introduction to Move Semantics
As we’ve seen, excessive calls to the copy constructor can hurt performance. In a move from source to target, instead of copying a resource, the target “steals” the resource from the source. The source contains a pointer to an object. The target gets a copy of the pointer. The source’s pointer is set to null. Therefore, the target has taken ownership of the object.
4
Introduction to Move Semantics, cont’d
Move semantics involve lvalues and rvalues. An lvalue is an object. So called because it can appear on the left side of an assignment statement (i.e., it can be an assignment target). An rvalue is a temporary value or a value not associated with an object. So called because it can be a value that’s calculated on the right side of an assignment statement.
5
Introduction to Move Semantics, cont’d
When an rvalue is assigned in an assignment statement, or when an rvalue is passed by value to a function, a copy is made of the value. But it is wasteful to copy a temporary value. That value normally is about to disappear. Move semantics allows us to use that temporary value by taking ownership of its resources. Reduce the amount of runtime copying.
6
Move Semantics Example
Message.h class Message { private: int length; char *text; public: Message() : length(0), text(nullptr) {} Message(char *t) : length(strlen(t)), text(t) {} virtual ~Message() { if (length > 0) delete[] text; length = 0; text = nullptr; }
7
Move Semantics Example, cont’d
Message(const Message& other) { cout << "*** Copy constructor called!" << endl; length = other.length; text = new char[length + 1]; strcpy(text, other.text); } Message(Message&& other) cout << "*** Move constructor called!" << endl; text = other.text; other.length = 0; other.text = nullptr; Copy constructor Copy the source’s data. Move constructor Steal the source’s data without copying it.
8
Move Semantics Example, cont’d
Message& operator =(const Message& other) { cout << "*** Copy assignment called!" << endl; if (this != &other) { if (length > 0) delete[] text; length = other.length; text = new char[length + 1]; strcpy(text, other.text); } return *this; } Copy assignment Message& operator =(Message&& other) { cout << "*** Move assignment called!" << endl; if (this != &other) { if (length > 0) delete[] text; length = other.length; text = other.text; other.length = 0; other.text = nullptr; } return *this; } Move assignment Steal the source’s data without copying it.
9
Move Semantics Example, cont’d
friend ostream& operator <<(ostream& outs, const Message& msg) { cout << msg.length << ":"; if (msg.text != nullptr) cout << msg.text; else cout << "<empty>"; return outs; }
10
Move Semantics Example, cont’d
TestMove.cpp char h[16], w[16]; strcpy(h, "hello"); strcpy(w, "world"); cout << "h = " << h << endl; cout << "w = " << w << endl; // Default constructor. cout << endl; Message msg; cout << "msg = " << msg << endl; // Regular constructor. Message hello1(h); Message world1(w); cout << "hello1 = " << hello1 << endl; cout << "world1 = " << world1 << endl; h = hello w = world *** Default constructor called. msg = 0:<empty> *** Regular constructor called: t = 'hello' *** Regular constructor called: t = 'world' hello1 = 5:hello world1 = 5:world
11
Move Semantics Example, cont’d
// Copy constructor. cout << endl; Message hello2(hello1); cout << "hello1 = " << hello1 << endl; cout << "hello2 = " << hello2 << endl; // Default constructor and copy assignment. Message world2; world2 = world1; cout << "world1 = " << world1 << endl; cout << "world2 = " << world2 << endl; *** Copy constructor called. hello1 = 5:hello hello2 = 5:hello *** Default constructor called. *** Copy assignment called. world1 = 5:world world2 = 5:world
12
Move Semantics Example, cont’d
// Move constructor. cout << endl; Message hello3(move(hello1)); cout << "hello1 = " << hello1 << endl; cout << "hello3 = " << hello3 << endl; // Default constructor and move assignment. Message world3; world3 = move(world1); cout << "world1 = " << world1 << endl; cout << "world3 = " << world3 << endl; // Destructor. cout << endl << "Done!" << endl; return 0; *** Move constructor called. hello1 = 0:<empty> hello3 = 5:hello *** Default constructor called. *** Move assignment called. world1 = 0:<empty> world3 = 5:world Done! *** Destructor called: text = 'world'
13
Review: Rule of the “Big Three”
If a class defines one or more of the following, it should explicitly define all three: Destructor Copy constructor Copy assignment operator The copy constructor and the copy assignment operator each does a deep copy.
14
Rule of the “Big Five” Explicitly define:
Destructor Copy constructor Copy assignment operator Move constructor Move assignment operator The move constructor and the move assignment operator can each steal resources from temporary source objects.
15
Introduction to Algorithm Analysis
To analyze an algorithm, we measure it. A convenient measure must be: A resource we care about (elapsed time, memory usage, etc.). Quantitative, to make comparisons possible. Easy to compute. A good predictor of the “goodness” of the algorithm. We will be concerned mostly with elapsed time.
16
Introduction to Algorithm Analysis, cont’d
Our concern generally is not how long a particular run of an algorithm will take, but how well the algorithm scales. How does the run time increase as the amount of input increases? Example: How does the reading time of a book increase as the number of pages increases? Example: How does the run time of a particular sort algorithm increase as the number of items to be sorted increases?
17
Introduction to Algorithm Analysis, cont’d
When we compare two algorithms, we want to compare how well they scale. How do their elapsed run times grow as the size of the input grows? How do their growth rates compare? Can we do this comparison without actually running the algorithms? Some algorithms may be too expensive to run.
18
Big-Oh Notation Let T(N) be the running time of an algorithm with N input values. T(N) = O(f(N)) if there are positive constants c and n0 such that T(N) ≤ cf(N) when N ≥ n0. O is the “big-oh” pronounced “order of” In other words, when N is sufficiently large, function f(N) is an upper bound for time function T(N). We don’t care about small values of N. T(N) will grow no faster than f(N) as N increases.
19
Big-Oh Notation, cont’d
T(N) cf(N) T(N) = O(f(N)) Upper bound
20
How Well Does an Algorithm Scale?
Data Structures and Algorithms in Java, 3rd ed. by Mark Allen Weiss Pearson Education, Inc., 2012 ISBN
21
How Well Does an Algorithm Scale? cont’d
Data Structures and Algorithms in Java, 3rd ed. by Mark Allen Weiss Pearson Education, Inc., 2012 ISBN
22
How Well Does an Algorithm Scale? cont’d
Data Structures and Algorithms in Java, 3rd ed. by Mark Allen Weiss Pearson Education, Inc., 2012 ISBN
23
How Well Does an Algorithm Scale? cont’d
Data Structures and Algorithms in Java, 3rd ed. by Mark Allen Weiss Pearson Education, Inc., 2012 ISBN
24
Partitioning a List of Values
“Divide and conquer” sorting algorithms require that the list first be split into smaller sublists that can be sorted separately. Then the sorted sublists can be recombined into a single sorted list. The sublists are usually sorted using recursion. Are there better ways to partition (split) a list of values other than down the middle?
25
Partitioning a List of Values, cont’d
Pick an arbitrary pivot value in the list. Move all the values less than the pivot value into one sublist. Move all the values greater than the pivot value into the other sublist. Now the pivot value is in its “final resting place”. It’s in the correct position for the sorted list. Recursively sort the two sublists. The pivot value doesn’t move. Challenge: Find a good pivot value.
26
Mark Allen Weiss Data Structures and Algorithms in Java (c) 2006 Pearson Education, Inc. All rights reserved
27
Partition a List Using a Pivot
Given a list, pick an element to be the pivot. There are various strategies to pick the pivot. The simplest is to pick the first element of the list. First get the chosen pivot value “out of the way” by swapping with the value currently at the right end.
28
Partition a List Using a Pivot, cont’d
Goal: Move all values < pivot to the left part of the list and all values > pivot to the right part of the list.
29
Partition a List Using a Pivot, cont’d
Set index i to the left end of the list and index j to one from the right end. While i < j: Move i right, skipping over values < pivot. Stop i when it reaches a value ≥ pivot. Move j left, skipping over values > pivot. Stop j when it reaches a value ≤ pivot. After both i and j have stopped, swap the values at i and j. i j
30
Partition a List Using a Pivot, cont’d
i j Move j: i j Swap: i j Move i and j: i j Swap: Move i and j. They’ve crossed! j i Swap the pivot with the ith element: j i Now the list is properly partitioned for quicksort!
31
Quicksort A fast divide-and-conquer sorting algorithm. Basic idea:
A very tight and highly optimized inner loop. Looks like magic in animation. Average running time is O(N log N) Worst-case running time is O(N2) The worst case be made to occur very unlikely. Basic idea: Partition the list using a pivot. Recursively sort the two sublists. One of the most elegant and useful algorithms in computer science.
32
Quicksort Pivot Strategy
Quicksort is a fragile algorithm! It is sensitive to picking a good pivot. Attempts to improve the algorithm can break it. Simplest pivot strategy: Pick the first element of each sublist. Worst strategy if the list is already sorted. Running time O(N2)
33
Median-of-Three Pivot Strategy
A good pivot value would be the median value of the list. The median of a list of unsorted numbers is nontrivial to compute. Compromise: Examine the two values at the ends of the list and the value at the middle position of the list. Choose the value that’s in between the other two.
34
Optimal Quicksort Median-of-three pivoting strategy.
SORTING from index 0 to 24 [ ] Paritioning with pivot 8 i = 1, j = 23, swapped 1 and 24 [ 5 1# # 8] i = 2, j = 19, swapped 2 and 8 [ 5 1 2# # ] i = 3, j = 18, swapped 8 and 10 [ # # ] i = 4, j = 17, swapped 8 and 23 [ # # ] i = 5, j = 9, swapped 8 and 14 [ # # ] i = 6, j = 5, swapped 17 and 8 [ # 17# ] Partitioned with pivot 8 at index 6 [ ]
35
Optimal Quicksort, cont’d
SORTING from index 0 to 5 [ ] Paritioning with pivot 5 [ ] i = 2, j = 1, swapped 8 and 1 [ 2 1# 8# 8 8 5] Partitioned with pivot 5 at index 2 [ ] SORTING from index 0 to 1 [ 2 1] Paritioning with pivot 1 i = 0, j = -1, swapped 2 and [ 2# 1] Partitioned with pivot 1 at index 0 [ 1 2] SORTED from index 0 to 1
36
Optimal Quicksort, cont’d
SORTING from index 3 to 5 1 2 5 [ 8 8 8] Paritioning with pivot 8 i = 3, j = 4, swapped 8 and 8 1 2 5 [ 8# 8# 8] i = 4, j = 3, swapped 8 and 8 Partitioned with pivot 8 at index 4 SORTED from index 3 to 5 SORTED from index 0 to 5 [ ]
37
Optimal Quicksort, cont’d
SORTING from index 7 to 24 [ ] Paritioning with pivot 17 i = 8, j = 22, swapped 11 and 17 [ 11 11# # 24 17] i = 10, j = 21, swapped 11 and 19 [ # # ] i = 11, j = 20, swapped 16 and 21 [ # # ] i = 15, j = 19, swapped 8 and 24 [ # # ] i = 16, j = 18, swapped 10 and 19 [ # 23 19# ] i = 17, j = 16, swapped 23 and 10 [ # 23# ] Partitioned with pivot 17 at index 17 [ ]
38
Optimal Quicksort, cont’d
SORTING from index 7 to 16 [ ] Paritioning with pivot 11 [ ] i = 8, j = 15, swapped 8 and 11 [ 10 8# # 11] i = 9, j = 12, swapped 9 and 14 [ # # ] i = 10, j = 10, swapped 11 and 11 [ # ] Partitioned with pivot 11 at index 10 [ ] SORTING from index 7 to 9 [ ] Paritioning with pivot 9 [ ] i = 8, j = 7, swapped 10 and 8 [ 8# 10# 9] Partitioned with pivot 9 at index 8 [ ] SORTED from index 7 to 9
39
Optimal Quicksort, cont’d
SORTING from index 11 to 16 [ ] Paritioning with pivot 16 [ ] i = 13, j = 15, swapped 11 and 16 [ # 16 16# 16] i = 14, j = 14, swapped 16 and 16 [ # 16 16] Partitioned with pivot 16 at index 14 [ ] SORTING from index 11 to 13 [ ] Paritioning with pivot 11 i = 11, j = 11, swapped 11 and 11 [ 11# 14 11] Partitioned with pivot 11 at index 11
40
Optimal Quicksort, cont’d
SORTING from index 12 to 13 [ 14 11] Paritioning with pivot 11 i = 12, j = 11, swapped 14 and 11 # [ 14# 11] Partitioned with pivot 11 at index 12 [ 11 14] SORTED from index 12 to 13 SORTED from index 11 to 13 [ ] SORTING from index 15 to 16 [ 16 16] Paritioning with pivot 16 i = 15, j = 15, swapped 16 and 16 [ 16# 16] Partitioned with pivot 16 at index 15 SORTED from index 15 to 16 SORTED from index 11 to 16 [ ] SORTED from index 7 to 16 [ ]
41
Optimal Quicksort, cont’d
SORTING from index 18 to 24 [ ] Paritioning with pivot 19 [ ] i = 18, j = 22, swapped 17 and 19 [ 17# # 24 19] i = 19, j = 18, swapped 24 and 17 [ 17# 24# ] Partitioned with pivot 19 at index 19 [ ] SORTING from index 20 to 24 [ ] Paritioning with pivot 21 [ ] i = 21, j = 20, swapped 23 and 19 [ 19# 23# ] Partitioned with pivot 21 at index 21 [ ]
42
Optimal Quicksort, cont’d
SORTING from index 22 to 24 [ ] Paritioning with pivot 24 [ ] i = 23, j = 23, swapped 24 and 24 [ 23 24# 24] Partitioned with pivot 24 at index 23 SORTED from index 22 to 24 SORTED from index 20 to 24 [ ] SORTED from index 18 to 24 [ ] SORTED from index 7 to 24 [ ] SORTED from index 0 to 24 [ ]
43
Quicksort, cont’d Quicksort doesn’t do well for very short lists.
When a sublist becomes too small, use another algorithm to sort the sublist such as insertion sort.
44
Sorting Animations
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.