Fast-Vector/src/test.cpp

152 lines
4.3 KiB
C++
Raw Normal View History

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;
}