lean4-htt/src/tests/util/pvector.cpp
Leonardo de Moura cd5e45bae2 Reduce pvector delta_cell quota on reads. Add example that demonstrates why this is needed.
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2013-09-12 08:28:24 -07:00

196 lines
5 KiB
C++

/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#include <iostream>
#include <cstdlib>
#include "test.h"
#include "pvector.h"
#include "timeit.h"
using namespace lean;
// #define PVECTOR_PERF_TEST
static void tst1() {
pvector<int> v;
lean_assert(v.empty());
v.push_back(10);
lean_assert(v.size() == 1);
lean_assert(v.back() == 10);
v.set(0, 20);
lean_assert(v.back() == 20);
v.pop_back();
lean_assert(v.size() == 0);
v.push_back(10);
v.push_back(20);
pvector<int> v2(v);
lean_assert(v2.size() == 2);
v2.push_back(30);
lean_assert(v.size() == 2);
lean_assert(v2.size() == 3);
v2.pop_back();
lean_assert(v.size() == 2);
v2.set(1, 100);
lean_assert(v[1] == 20);
lean_assert(v2[1] == 100);
for (unsigned i = 0; i < 100; i++)
v2.push_back(i);
}
template<typename T>
bool operator==(pvector<T> v1, std::vector<T> const & v2) {
if (v1.size() != v2.size())
return false;
for (unsigned i = 0; i < v1.size(); i++) {
if (v1[i] != v2[i])
return false;
}
return true;
}
static void driver(unsigned max_sz, unsigned max_val, unsigned num_ops, double push_freq, double copy_freq) {
std::vector<int> v1;
pvector<int> v2;
std::vector<pvector<int>> copies;
for (unsigned i = 0; i < num_ops; i++) {
double f = static_cast<double>(std::rand() % 10000) / 10000.0;
if (f < copy_freq)
copies.push_back(v2);
f = static_cast<double>(std::rand() % 10000) / 10000.0;
if (f < push_freq) {
if (v1.size() >= max_sz)
continue;
int a = std::rand() % max_val;
v1.push_back(a);
v2.push_back(a);
} else {
if (v1.size() == 0)
continue;
lean_assert(v1.back() == v2.back());
v1.pop_back();
v2.pop_back();
}
lean_assert(v2 == v1);
}
std::cout << "Copies created: " << copies.size() << "\n";
}
static void tst2() {
driver(4, 32, 10000, 0.5, 0.01);
driver(4, 32, 10000, 0.5, 0.1);
driver(2, 32, 10000, 0.8, 0.4);
driver(2, 32, 10000, 0.3, 0.5);
driver(4, 32, 10000, 0.3, 0.7);
driver(16, 32, 10000, 0.5, 0.1);
driver(16, 32, 10000, 0.5, 0.01);
driver(16, 32, 10000, 0.5, 0.5);
driver(16, 32, 10000, 0.7, 0.1);
driver(16, 32, 10000, 0.7, 0.5);
driver(16, 32, 10000, 0.7, 0.01);
driver(16, 32, 10000, 0.1, 0.5);
driver(16, 32, 10000, 0.8, 0.2);
driver(128, 1000, 10000, 0.5, 0.5);
driver(128, 1000, 10000, 0.5, 0.01);
driver(128, 1000, 10000, 0.5, 0.1);
driver(128, 1000, 10000, 0.2, 0.5);
driver(128, 1000, 10000, 0.2, 0.01);
driver(128, 1000, 10000, 0.2, 0.1);
}
static void tst3() {
timeit t(std::cout, "tst3");
unsigned N = 20000;
unsigned M = 20000;
pvector<int> v;
for (unsigned i = 0; i < N; i++) v.push_back(i);
pvector<int> v2 = v;
for (unsigned i = 0; i < N / 2; i++) v2.push_back(i);
// v2 has a long trail of deltas
// Now, we only read v2
unsigned s = 0;
for (unsigned i = 0; i < M; i++) { s += v2[i % v2.size()]; }
}
#ifdef PVECTOR_PERF_TEST
static void perf_vector(unsigned n) {
std::vector<int> q;
for (unsigned i = 0; i < n; i++) {
q.push_back(i);
}
for (unsigned i = 0; i < n; i++) {
q.pop_back();
}
}
static void perf_pvector(unsigned n) {
pvector<int> q;
for (unsigned i = 0; i < n; i++) {
q.push_back(i);
}
for (unsigned i = 0; i < n; i++) {
q.pop_back();
}
}
static void tst_perf1() {
unsigned N = 100000;
unsigned M = 100;
{
timeit t(std::cout, "vector time");
for (unsigned i = 0; i < N; i++) perf_vector(M);
}
{
timeit t(std::cout, "pvector time");
for (unsigned i = 0; i < N; i++) perf_pvector(M);
}
}
static void perf_vector2(std::vector<int> q, unsigned n) {
for (unsigned i = 0; i < n; i++) {
q.push_back(i);
}
for (unsigned i = 0; i < n; i++) {
q.pop_back();
}
}
static void perf_pvector2(pvector<int> q, unsigned n) {
for (unsigned i = 0; i < n; i++) {
q.push_back(i);
}
for (unsigned i = 0; i < n; i++) {
q.pop_back();
}
}
static void tst_perf2() {
unsigned N = 100000;
unsigned SZ1 = 10000;
unsigned M = 10;
{
timeit t(std::cout, "vector time");
std::vector<int> q;
for (unsigned i = 0; i < SZ1; i++) { q.push_back(i); }
for (unsigned i = 0; i < N; i++) perf_vector2(q, M);
}
{
timeit t(std::cout, "pvector time");
pvector<int> q;
for (unsigned i = 0; i < SZ1 + 1; i++) { q.push_back(i); }
for (unsigned i = 0; i < N; i++) perf_pvector2(q, M);
}
}
#endif
int main() {
tst1();
tst2();
tst3();
#ifdef PVECTOR_PERF_TEST
tst_perf1();
tst_perf2();
#endif
return has_violations() ? 1 : 0;
}