#pragma once
#include <chrono>
#include <type_traits>
template <typename Clock>
class stopwatch
{
public:
typedef Clock clock;
typedef typename clock::time_point time_point;
typedef typename clock::duration duration;
private:
time_point last_;
public:
stopwatch()
: last_(clock::now())
{}
void reset()
{
*this = stopwatch();
}
time_point now() const
{
return clock::now();
}
duration elapsed() const
{
return now() - last_;
}
duration tick()
{
time_point dummy;
return tick(dummy);
}
duration tick(time_point& now_)
{
now_ = now();
auto elapsed = now_ - last_;
last_ = now_;
return elapsed;
}
};
typedef stopwatch<std::chrono::steady_clock> default_stopwatch;
template <typename T, typename Rep, typename Period,
typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
T float_cast(const std::chrono::duration<Rep, Period>& duration, T mul = T(1))
{
return duration.count() * mul * (T(Period::num) / T(Period::den));
}
#include <cstring>
#include <algorithm>
#include <array>
#include <functional>
#include <iostream>
#include <random>
template <typename RNG>
RNG make_rng()
{
std::random_device rd;
std::array<typename RNG::result_type, RNG::state_size> seed_data;
std::generate(seed_data.begin(), seed_data.end(), std::ref(rd));
std::seed_seq seq(seed_data.begin(), seed_data.end());
return RNG(seq);
}
template <typename RNG>
void test_rng(RNG& rng, void* buffer, std::size_t size)
{
while (size >= sizeof(decltype(rng())))
{
auto r = rng();
std::memcpy(buffer, &r, sizeof r);
buffer = static_cast<char*>(buffer) + sizeof r;
size -= sizeof r;
}
}
int main()
{
const std::size_t mb = 512;
std::vector<char> buf(mb * 1024 * 1024);
default_stopwatch sw;
double t;
auto rng1 = make_rng<std::mt19937>();
auto rng2 = make_rng<std::mt19937_64>();
auto rng3 = std::minstd_rand((std::random_device()()));
sw.reset();
test_rng(rng1, buf.data(), buf.size());
t = float_cast<double>(sw.elapsed());
std::cout << "mt19937: " << t << " - " << mb / t << " MB/s\n";
sw.reset();
test_rng(rng2, buf.data(), buf.size());
t = float_cast<double>(sw.elapsed());
std::cout << "mt19937_64: " << t << " - " << mb / t << " MB/s\n";
sw.reset();
test_rng(rng3, buf.data(), buf.size());
t = float_cast<double>(sw.elapsed());
std::cout << "minstd_rand: " << t << " - " << mb / t << " MB/s\n";
}
CiNwcmFnbWEgb25jZQoKI2luY2x1ZGUgPGNocm9ubz4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGUgPHR5cGVuYW1lIENsb2NrPgpjbGFzcyBzdG9wd2F0Y2gKewpwdWJsaWM6Cgl0eXBlZGVmIENsb2NrIGNsb2NrOwoJdHlwZWRlZiB0eXBlbmFtZSBjbG9jazo6dGltZV9wb2ludCB0aW1lX3BvaW50OwoJdHlwZWRlZiB0eXBlbmFtZSBjbG9jazo6ZHVyYXRpb24gZHVyYXRpb247Cgpwcml2YXRlOgoJdGltZV9wb2ludCBsYXN0XzsKCnB1YmxpYzoKCXN0b3B3YXRjaCgpCgkJOiBsYXN0XyhjbG9jazo6bm93KCkpCgl7fQoKCXZvaWQgcmVzZXQoKQoJewoJCSp0aGlzID0gc3RvcHdhdGNoKCk7Cgl9CgoJdGltZV9wb2ludCBub3coKSBjb25zdAoJewoJCXJldHVybiBjbG9jazo6bm93KCk7Cgl9CgoJZHVyYXRpb24gZWxhcHNlZCgpIGNvbnN0Cgl7CgkJcmV0dXJuIG5vdygpIC0gbGFzdF87Cgl9CgoJZHVyYXRpb24gdGljaygpCgl7CgkJdGltZV9wb2ludCBkdW1teTsKCQlyZXR1cm4gdGljayhkdW1teSk7Cgl9CgoJZHVyYXRpb24gdGljayh0aW1lX3BvaW50JiBub3dfKQoJewoJCW5vd18gPSBub3coKTsKCQlhdXRvIGVsYXBzZWQgPSBub3dfIC0gbGFzdF87CgkJbGFzdF8gPSBub3dfOwoJCXJldHVybiBlbGFwc2VkOwoJfQp9OwoKdHlwZWRlZiBzdG9wd2F0Y2g8c3RkOjpjaHJvbm86OnN0ZWFkeV9jbG9jaz4gZGVmYXVsdF9zdG9wd2F0Y2g7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUmVwLCB0eXBlbmFtZSBQZXJpb2QsIAoJdHlwZW5hbWUgPSB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxzdGQ6OmlzX2Zsb2F0aW5nX3BvaW50PFQ+Ojp2YWx1ZT46OnR5cGU+ClQgZmxvYXRfY2FzdChjb25zdCBzdGQ6OmNocm9ubzo6ZHVyYXRpb248UmVwLCBQZXJpb2Q+JiBkdXJhdGlvbiwgVCBtdWwgPSBUKDEpKQp7CglyZXR1cm4gZHVyYXRpb24uY291bnQoKSAqIG11bCAqIChUKFBlcmlvZDo6bnVtKSAvIFQoUGVyaW9kOjpkZW4pKTsKfQoKCiNpbmNsdWRlIDxjc3RyaW5nPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8YXJyYXk+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxyYW5kb20+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgUk5HPgpSTkcgbWFrZV9ybmcoKQp7CglzdGQ6OnJhbmRvbV9kZXZpY2UgcmQ7CglzdGQ6OmFycmF5PHR5cGVuYW1lIFJORzo6cmVzdWx0X3R5cGUsIFJORzo6c3RhdGVfc2l6ZT4gc2VlZF9kYXRhOwoJc3RkOjpnZW5lcmF0ZShzZWVkX2RhdGEuYmVnaW4oKSwgc2VlZF9kYXRhLmVuZCgpLCBzdGQ6OnJlZihyZCkpOwoJc3RkOjpzZWVkX3NlcSBzZXEoc2VlZF9kYXRhLmJlZ2luKCksIHNlZWRfZGF0YS5lbmQoKSk7CglyZXR1cm4gUk5HKHNlcSk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBSTkc+CnZvaWQgdGVzdF9ybmcoUk5HJiBybmcsIHZvaWQqIGJ1ZmZlciwgc3RkOjpzaXplX3Qgc2l6ZSkKewoJd2hpbGUgKHNpemUgPj0gc2l6ZW9mKGRlY2x0eXBlKHJuZygpKSkpCgl7CgkJYXV0byByID0gcm5nKCk7CgkJc3RkOjptZW1jcHkoYnVmZmVyLCAmciwgc2l6ZW9mIHIpOwoJCWJ1ZmZlciA9IHN0YXRpY19jYXN0PGNoYXIqPihidWZmZXIpICsgc2l6ZW9mIHI7CgkJc2l6ZSAtPSBzaXplb2YgcjsKCX0KfQoKaW50IG1haW4oKQp7Cgljb25zdCBzdGQ6OnNpemVfdCBtYiA9IDUxMjsKCXN0ZDo6dmVjdG9yPGNoYXI+IGJ1ZihtYiAqIDEwMjQgKiAxMDI0KTsKCWRlZmF1bHRfc3RvcHdhdGNoIHN3OwoJZG91YmxlIHQ7CglhdXRvIHJuZzEgPSBtYWtlX3JuZzxzdGQ6Om10MTk5Mzc+KCk7CglhdXRvIHJuZzIgPSBtYWtlX3JuZzxzdGQ6Om10MTk5MzdfNjQ+KCk7CglhdXRvIHJuZzMgPSBzdGQ6Om1pbnN0ZF9yYW5kKChzdGQ6OnJhbmRvbV9kZXZpY2UoKSgpKSk7CgoJc3cucmVzZXQoKTsKCXRlc3Rfcm5nKHJuZzEsIGJ1Zi5kYXRhKCksIGJ1Zi5zaXplKCkpOwoJdCA9IGZsb2F0X2Nhc3Q8ZG91YmxlPihzdy5lbGFwc2VkKCkpOwoJc3RkOjpjb3V0IDw8ICJtdDE5OTM3OiAiIDw8IHQgPDwgIiAtICIgPDwgbWIgLyB0IDw8ICIgTUIvc1xuIjsKCglzdy5yZXNldCgpOwoJdGVzdF9ybmcocm5nMiwgYnVmLmRhdGEoKSwgYnVmLnNpemUoKSk7Cgl0ID0gZmxvYXRfY2FzdDxkb3VibGU+KHN3LmVsYXBzZWQoKSk7CglzdGQ6OmNvdXQgPDwgIm10MTk5MzdfNjQ6ICIgPDwgdCA8PCAiIC0gIiA8PCBtYiAvIHQgPDwgIiBNQi9zXG4iOwoKCXN3LnJlc2V0KCk7Cgl0ZXN0X3JuZyhybmczLCBidWYuZGF0YSgpLCBidWYuc2l6ZSgpKTsKCXQgPSBmbG9hdF9jYXN0PGRvdWJsZT4oc3cuZWxhcHNlZCgpKTsKCXN0ZDo6Y291dCA8PCAibWluc3RkX3JhbmQ6ICIgPDwgdCA8PCAiIC0gIiA8PCBtYiAvIHQgPDwgIiBNQi9zXG4iOwp9