-
Notifications
You must be signed in to change notification settings - Fork 13
/
Ex0108_PerformanceMeasurement.cpp
150 lines (121 loc) · 3.74 KB
/
Ex0108_PerformanceMeasurement.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <cassert>
#include <chrono>
#include <fstream>
#include <algorithm> // swap
using namespace std;
using namespace std::chrono;
void Print(int* arr, int size)
{
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
void ShuffleArray(int arr[], int n)
{
for (int i = n - 1; i > 0; i--) {
int j = rand() % (i + 1);
swap(arr[i], arr[j]);
}
}
int SequentialSearch(int* arr, int n, int x)
{
int i;
for (i = 0; i < n && arr[i] != x; i++);
if (i == n) return -1;
else return i;
}
int BinarySearch(int* arr, int n, int x)
{
int left = 0;
int right = n - 1;
while (left <= right)
{
int middle = (left + right) / 2; // 정수 나누기 (버림)
if (x < arr[middle])
right = middle - 1;
else if (x > arr[middle])
left = middle + 1;
else
return middle;
}
return -1; // Not found
}
int main()
{
// auto는 컴파일러가 등호 오른쪽을 보고 변수의 자료형을 알아서 결정
// 예: auto f = 3.141592f; // f는 float
// 예: auto d = 3.14; // d는 double
// 주의
// - 속도 측정할 때는 release 모드 사용
// - 프로젝트 옵션에서 최적화 off (Optimization /Od)
// - 반환값을 result로 받지 않으면 최적화에서 실행 생략
const int kNumTest = int(pow(2, 18));
// 데이터 준비 (kNumTest개 초기화하고 n만 바꿔가면서 테스트)
ofstream ofile("performance.txt"); // TEST 1
//ofstream ofile("performance_worst.txt"); // TEST 2
//for (int n = 1; n <= kNumTest; n *= 2) // n은 1이상 kNumTest이하
for (int n = 1; n <= kNumTest; n += int(pow(2, 10)))
{
int* x_table = new int[n + 1];
for (int i = 0; i < n; i++) {
x_table[i] = i;
}
x_table[n] = n;
ShuffleArray(x_table, n + 1);
double seq_sum = 0.0;
double bi_sum = 0.0;
double seq_max = 0.0; // 가장 큰 값 (worst)
double bi_max = 0.0;
double seq_min = 10000.0;
double bi_min = 10000.0;
for (int x = 0; x < n + 1; x++) // 못 찾는 경우를 하나 마지막에 추가
{
int result_seq;
int result_bi;
int x_find = x_table[x];
// Sequential Search
{
int* arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = i;
auto start = high_resolution_clock::now();
result_seq = SequentialSearch(arr, n, x_find); // TEST 1
//result_seq = SequentialSearch(arr, n, n + rand() % 1000); // TEST 2 <- 항상 못찾도록
auto stop = high_resolution_clock::now();
auto duration = double(duration_cast<nanoseconds>(stop - start).count()) / 1000.0;
seq_sum += duration;
seq_max = std::max(duration, seq_max);
seq_min = std::min(duration, seq_min);
delete[] arr;
}
// Binary Search
{
int* arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = i;
auto start = high_resolution_clock::now();
result_bi = BinarySearch(arr, n, x_find); // TEST 1
// result_bi = BinarySearch(arr, n, n + rand() % 1000); // TEST 2<- 항상 못찾도록
auto stop = high_resolution_clock::now();
auto duration = double(duration_cast<nanoseconds>(stop - start).count()) / 1000.0;
bi_sum += duration;
bi_max = std::max(duration, bi_max);
bi_min = std::min(duration, bi_min);
delete[] arr;
}
if (result_bi != result_seq)
{
cout << "Wrong " << result_seq << " " << result_bi << endl;
exit(0);
}
}
seq_sum /= n + 1; // <- 변수 이름은 sum 이지만 실제로는 평균
bi_sum /= n + 1; // <- 변수 이름은 sum 이지만 실제로는 평균
cout << n << ", " << seq_max << ", " << bi_max << ", " << seq_sum << ", " << bi_sum << ", " << seq_min << ", " << bi_min << endl;
ofile << n << ", " << seq_max << ", " << bi_max << ", " << seq_sum << ", " << bi_sum << ", " << seq_min << ", " << bi_min << endl;
delete[] x_table;
}
ofile.close();
return 0;
}