diff --git a/pretext/AlgorithmAnalysis/HashTableAnalysis.ptx b/pretext/AlgorithmAnalysis/HashTableAnalysis.ptx
index 08d32d92..ff14fcc9 100755
--- a/pretext/AlgorithmAnalysis/HashTableAnalysis.ptx
+++ b/pretext/AlgorithmAnalysis/HashTableAnalysis.ptx
@@ -91,70 +91,93 @@
advantage of the hash table is the constant speed of the
For our last performance experiment we will compare the performance of
- the contains operation between vectors and hash tables. In the process we
- will confirm that the contains operation for vectors is
We will repeat the same experiment for a hash table that contains - numbers as the keys. In this experiment we should see that determining + numbers as the keys. In this experiment we should see that finding whether or not a number is in the hash table is not only much faster, - but the time it takes to check should remain constant even as the - hash table grows larger.
+ but the time it takes to search should remain roughly constant even as + the hash table grows larger. Note that in both cases we only time the + search itself — filling each container is done first and is not included + in the measurement, since we want to isolate the cost of the search + operation.
+#include <algorithm>
+#include <chrono>
+#include <iomanip>
#include <iostream>
-#include <ctime>
-#include <vector>
+#include <numeric>
#include <unordered_map>
+#include <vector>
using namespace std;
int main() {
- for(int a = 10000; a < 1000001; a = a + 20000) {
- vector<int> avector;
- unordered_map<int, int> amap;
+ cout << setw(10) << "size"
+ << setw(15) << "vector (s)"
+ << setw(15) << "hash table (s)" << endl;
- // create the vector and map
- for( int i = 0; i < a; i++){
- avector.push_back(i);
- amap[i] = -1;
+ for(int a = 10000; a < 1000001; a = a + 20000) {
+ // build and fill the vector (not timed)
+ vector<int> avector(a);
+ iota(avector.begin(), avector.end(), 0);
+
+ // time searching the vector for every value
+ auto begin = chrono::steady_clock::now();
+ for(int i = 0; i < a; i++){
+ if (find(avector.begin(), avector.end(), i) == avector.end()) {
+ cerr << "value not found in vector!" << endl;
+ return 1;
+ }
}
+ auto end = chrono::steady_clock::now();
+ chrono::duration<double> elapsed_secs = end - begin;
+ double avg_vector_time = elapsed_secs.count() / a;
- // timing for vector access
- srand(1);
- clock_t begin = clock();
- for( int i = 0; i < a; i++){
- find(avector.begin(), avector.end(), rand() % a);
+ // build and fill the hash table (not timed)
+ unordered_map<int, int> amap;
+ for(int i = 0; i < a; i++){
+ amap[i] = i;
}
- clock_t end = clock();
- double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
-
- // timing for hash table
- srand(1);
- clock_t begin_ht = clock();
- for( int i = 0; i < a; i++ ){
- amap.contains(rand() % a);
+
+ // time searching the hash table for every value
+ auto begin_ht = chrono::steady_clock::now();
+ for(int i = 0; i < a; i++){
+ if (amap.find(i) == amap.end()) {
+ cerr << "value not found in hash table!" << endl;
+ return 2;
+ }
}
- clock_t end_ht = clock();
- double elapsed_secs_ht = double(end_ht - begin_ht) / CLOCKS_PER_SEC;
+ auto end_ht = chrono::steady_clock::now();
+ chrono::duration<double> elapsed_secs_ht = end_ht - begin_ht;
+ double avg_hashtable_time = elapsed_secs_ht.count() / a;
// Printing final output
- cout << a << "\t" << elapsed_secs << "\t" << elapsed_secs_ht << endl;
+ cout << setw(10) << a
+ << setw(15) << avg_vector_time
+ << setw(15) << avg_hashtable_time << endl;
}
return 0;
}
- Running
Since C++ is an evolving language, there are always changes going on behind the scenes. The latest information on the performance of C++