// Operaciones en un extremo: un arreglo con capacidad que crece frente a una lista doble.
// Compilar con -O2 y sin sanitizers. Los tiempos dependen de la máquina.
#include <cstddef>
#include <cstdio>
#include <vector>

#include "bench.h"
#include "dlist.h"

namespace {

const int REPS = 7;

template <typename Sequence>
double push_then_pop(std::size_t n) {
    double seconds = median_seconds(REPS, [&] {
        Sequence sequence;
        for (std::size_t i = 0; i < n; i++) {
            sequence.push_back(static_cast<int>(i));
        }
        while (!sequence.empty()) {
            keep(sequence.back());
            sequence.pop_back();
        }
    });
    return seconds * 1e9 / static_cast<double>(2 * n);
}

}  // namespace

int main() {
    std::printf("%8s %10s %8s %7s\n", "n", "std::vector", "DList", "razón");
    for (std::size_t n = 10000; n <= 1000000; n *= 10) {
        double array_ns = push_then_pop<std::vector<int>>(n);
        double list_ns = push_then_pop<DList<int>>(n);
        std::printf("%8zu %10.2f %8.2f %6.1f\n", n, array_ns, list_ns, list_ns / array_ns);
    }
    return 0;
}
