2025-04-17 03:24:46 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
#include <chrono>
|
|
|
|
#include <iomanip>
|
|
|
|
|
|
|
|
#include "vector.h"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace std::chrono;
|
|
|
|
|
|
|
|
static constexpr size_t N = 100'000'000;
|
|
|
|
static constexpr int R = 3;
|
|
|
|
|
|
|
|
constexpr const char* COLOR_RESET = "\033[0m";
|
|
|
|
constexpr const char* COLOR_RED = "\033[31m";
|
|
|
|
constexpr const char* COLOR_GREEN = "\033[32m";
|
|
|
|
|
|
|
|
template<typename F>
|
|
|
|
double run_bench(F&& fn) {
|
|
|
|
auto start = steady_clock::now();
|
|
|
|
fn();
|
|
|
|
auto end = steady_clock::now();
|
|
|
|
return duration_cast<duration<double, milli>>(end - start).count();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename F>
|
|
|
|
double run_avg(F&& fn) {
|
|
|
|
double total = 0.0;
|
|
|
|
for (int i = 0; i < R; ++i) {
|
|
|
|
total += run_bench(fn);
|
|
|
|
}
|
|
|
|
return total / R;
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_test(const std::string& name, double std_t, double fast_t) {
|
|
|
|
double speedup = std_t / fast_t;
|
|
|
|
bool passed = fast_t < std_t;
|
|
|
|
const char* status_col = passed ? COLOR_GREEN : COLOR_RED;
|
|
|
|
const char* status_str = passed ? "[PASS]" : "[FAIL]";
|
|
|
|
|
|
|
|
cout << status_col << status_str << COLOR_RESET
|
2025-04-17 03:25:16 +00:00
|
|
|
<< ' ' << std::left << std::setw(27) << name
|
2025-04-17 03:24:46 +00:00
|
|
|
<< " | std: " << std::right << std::setw(7) << fixed << setprecision(2) << std_t << "ms"
|
|
|
|
<< " | fast: " << setw(7) << fast_t << "ms"
|
|
|
|
<< " | x" << status_col << setw(5) << fixed << setprecision(2) << speedup << COLOR_RESET
|
|
|
|
<< '\n';
|
|
|
|
}
|
|
|
|
|
|
|
|
struct S {
|
|
|
|
int x, y;
|
|
|
|
S(int a, int b): x(a), y(b) {}
|
|
|
|
S(const S& o): x(o.x), y(o.y) {}
|
|
|
|
S(S&& o) noexcept: x(o.x), y(o.y) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
void TestIntPush_NoReserve() {
|
|
|
|
auto std_fn = []() {
|
|
|
|
vector<int> v;
|
|
|
|
for (size_t i = 0; i < N; ++i) v.push_back(int(i));
|
|
|
|
};
|
|
|
|
auto fast_fn = []() {
|
|
|
|
Vector<int> v;
|
|
|
|
for (size_t i = 0; i < N; ++i) v.push_back(int(i));
|
|
|
|
};
|
|
|
|
double t1 = run_avg(std_fn);
|
|
|
|
double t2 = run_avg(fast_fn);
|
|
|
|
print_test("IntPush_NoReserve", t1, t2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestIntPush_WithReserve() {
|
|
|
|
auto std_fn = []() {
|
|
|
|
vector<int> v; v.reserve(N);
|
|
|
|
for (size_t i = 0; i < N; ++i) v.push_back(int(i));
|
|
|
|
};
|
|
|
|
auto fast_fn = []() {
|
|
|
|
Vector<int> v; v.reserve(N);
|
|
|
|
for (size_t i = 0; i < N; ++i) v.push_back(int(i));
|
|
|
|
};
|
|
|
|
double t1 = run_avg(std_fn);
|
|
|
|
double t2 = run_avg(fast_fn);
|
|
|
|
print_test("IntPush_WithReserve", t1, t2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestIntEmplace_NoReserve() {
|
|
|
|
auto std_fn = []() {
|
|
|
|
vector<int> v;
|
|
|
|
for (size_t i = 0; i < N; ++i) v.emplace_back(int(i));
|
|
|
|
};
|
|
|
|
auto fast_fn = []() {
|
|
|
|
Vector<int> v;
|
|
|
|
for (size_t i = 0; i < N; ++i) v.emplace_back(int(i));
|
|
|
|
};
|
|
|
|
double t1 = run_avg(std_fn);
|
|
|
|
double t2 = run_avg(fast_fn);
|
|
|
|
print_test("IntEmplace_NoReserve", t1, t2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestIntEmplace_WithReserve() {
|
|
|
|
auto std_fn = []() {
|
|
|
|
vector<int> v; v.reserve(N);
|
|
|
|
for (size_t i = 0; i < N; ++i) v.emplace_back(int(i));
|
|
|
|
};
|
|
|
|
auto fast_fn = []() {
|
|
|
|
Vector<int> v; v.reserve(N);
|
|
|
|
for (size_t i = 0; i < N; ++i) v.emplace_back(int(i));
|
|
|
|
};
|
|
|
|
double t1 = run_avg(std_fn);
|
|
|
|
double t2 = run_avg(fast_fn);
|
|
|
|
print_test("IntEmplace_WithReserve", t1, t2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestNonTrivialPush_NoReserve() {
|
|
|
|
auto std_fn = []() {
|
|
|
|
vector<S> v;
|
|
|
|
for (size_t i = 0; i < N/10; ++i) v.push_back(S(int(i), int(i)));
|
|
|
|
};
|
|
|
|
auto fast_fn = []() {
|
|
|
|
Vector<S> v;
|
|
|
|
for (size_t i = 0; i < N/10; ++i) v.push_back(S(int(i), int(i)));
|
|
|
|
};
|
|
|
|
double t1 = run_avg(std_fn);
|
|
|
|
double t2 = run_avg(fast_fn);
|
|
|
|
print_test("NonTrivialPush_NoReserve", t1, t2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestNonTrivialPush_WithReserve() {
|
|
|
|
auto std_fn = []() {
|
|
|
|
vector<S> v; v.reserve(N/10);
|
|
|
|
for (size_t i = 0; i < N/10; ++i) v.push_back(S(int(i), int(i)));
|
|
|
|
};
|
|
|
|
auto fast_fn = []() {
|
|
|
|
Vector<S> v; v.reserve(N/10);
|
|
|
|
for (size_t i = 0; i < N/10; ++i) v.push_back(S(int(i), int(i)));
|
|
|
|
};
|
|
|
|
double t1 = run_avg(std_fn);
|
|
|
|
double t2 = run_avg(fast_fn);
|
|
|
|
print_test("NonTrivialPush_WithReserve", t1, t2);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
cout << "\n=== Running Speed Tests (N=" << N << ", runs=" << R << ") ===\n\n";
|
|
|
|
TestIntPush_NoReserve();
|
|
|
|
TestIntPush_WithReserve();
|
|
|
|
TestIntEmplace_NoReserve();
|
|
|
|
TestIntEmplace_WithReserve();
|
|
|
|
TestNonTrivialPush_NoReserve();
|
|
|
|
TestNonTrivialPush_WithReserve();
|
|
|
|
cout << "\n";
|
|
|
|
return 0;
|
|
|
|
}
|