Last active
November 24, 2019 22:10
-
-
Save mmore500/8747e456b949b5b18b3ee85dd9b4444d to your computer and use it in GitHub Desktop.
emp::Random::GetUInt64 profile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is the main function for the NATIVE version of this project. | |
#include <iostream> | |
#include <chrono> | |
#include "base/vector.h" | |
#include "config/command_line.h" | |
#include "tools/Random.h" | |
#include "data/DataFile.h" | |
int main(int argc, char* argv[]) | |
{ | |
emp::Random rand(1); | |
double sum = 0.0; | |
emp::DataFile dfile("timings.dat"); | |
std::string type; | |
double timing; | |
dfile.AddVar<std::string>(type, "type"); | |
dfile.AddVar<double>(timing, "timing"); | |
dfile.PrintHeaderKeys(); | |
for (size_t rep = 0; rep < 500; ++rep) { | |
std::cout << "." << std::endl; | |
{ | |
type = "old"; | |
const auto start = std::chrono::high_resolution_clock::now(); | |
for (size_t i = 0; i < 1e5; ++i) { | |
sum += rand.GetUInt64Old(); | |
} | |
const auto stop = std::chrono::high_resolution_clock::now(); | |
timing = std::chrono::duration_cast<std::chrono::microseconds>( | |
stop - start | |
).count(); | |
dfile.Update(); | |
} | |
{ | |
type = "new"; | |
const auto start = std::chrono::high_resolution_clock::now(); | |
for (size_t i = 0; i < 1e5; ++i) { | |
sum += rand.GetUInt64(); | |
} | |
const auto stop = std::chrono::high_resolution_clock::now(); | |
timing = std::chrono::duration_cast<std::chrono::microseconds>( | |
stop - start | |
).count(); | |
dfile.Update(); | |
} | |
std::cout << sum << std::endl; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
import seaborn as sns | |
import matplotlib.pyplot as plt | |
df = pd.read_csv("timings.dat") | |
sns.barplot(data=df, y="timing", x="type") | |
plt.savefig("out.pdf") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @note This file is part of Empirical, https://github.com/devosoft/Empirical | |
* @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md | |
* @date 2015-2019 | |
* | |
* @file Random.h | |
* @brief A versatile and non-patterned pseudo-random-number generator. | |
* @note Status: RELEASE | |
*/ | |
#ifndef EMP_RANDOM_H | |
#define EMP_RANDOM_H | |
#include <ctime> | |
#include <climits> | |
#include <cmath> | |
#include <cstring> | |
#include <iterator> | |
#include "../base/assert.h" | |
#include "Range.h" | |
namespace emp { | |
/// A versatile and non-patterned pseudo-random-number generator (Mersenne Twister). | |
class Random { | |
protected: | |
int seed = 0; ///< Current random number seed. | |
int original_seed = 0; ///< Orignal random number seed when object was first created. | |
int inext = 0; ///< First position in use in internal state. | |
int inextp = 0; ///< Second position in use in internal state. | |
int ma[56]; ///< Internal state of RNG | |
// Members & functions for stat functions | |
double expRV = 0.0; ///< Exponential Random Variable for the randNormal function | |
// Constants //////////////////////////////////////////////////////////////// | |
// Statistical Approximation | |
static const int32_t _BINOMIAL_TO_NORMAL = 50; // if < n*p*(1-p) | |
static const int32_t _BINOMIAL_TO_POISSON = 1000; // if < n && !Normal approx Engine | |
// Engine | |
static const int32_t _RAND_MBIG = 1000000000; | |
static const int32_t _RAND_MSEED = 161803398; | |
// Internal functions | |
// Setup, called on initialization and seed reset. | |
void init() | |
{ | |
// Clear variables | |
for (int i = 0; i < 56; ++i) ma[i] = 0; | |
int32_t mj = (_RAND_MSEED - seed) % _RAND_MBIG; | |
ma[55] = mj; | |
int32_t mk = 1; | |
for (int32_t i = 1; i < 55; ++i) { | |
int32_t ii = (21 * i) % 55; | |
ma[ii] = mk; | |
mk = mj - mk; | |
if (mk < 0) mk += _RAND_MBIG; | |
mj = ma[ii]; | |
} | |
for (int32_t k = 0; k < 4; ++k) { | |
for (int32_t j = 1; j < 55; ++j) { | |
ma[j] -= ma[1 + (j + 30) % 55]; | |
if (ma[j] < 0) ma[j] += _RAND_MBIG; | |
} | |
} | |
inext = 0; | |
inextp = 31; | |
// Setup variables used by Statistical Distribution functions | |
expRV = -log(Random::Get() / (double) _RAND_MBIG); | |
} | |
// Basic Random number | |
// Returns a random number [0,_RAND_MBIG) | |
int32_t Get() { | |
if (++inext == 56) inext = 0; | |
if (++inextp == 56) inextp = 0; | |
int mj = ma[inext] - ma[inextp]; | |
if (mj < 0) mj += _RAND_MBIG; | |
ma[inext] = mj; | |
return mj; | |
} | |
public: | |
/** | |
* Set up the random generator object. | |
* @param _seed The seed of the random number generator. A negative seed means that the | |
* random number generator gets its seed from a combination of the actual system time and | |
* the memory position of the random number generator. | |
**/ | |
Random(const int _seed = -1) { | |
for (int i = 0; i < 56; ++i) ma[i] = 0; | |
ResetSeed(_seed); // Calls init() | |
} | |
~Random() { ; } | |
/** | |
* @return The seed that was actually used to start the random sequence. | |
**/ | |
inline int GetSeed() const { return seed; } | |
/** | |
* @return The seed that was originally provided by the user. | |
**/ | |
inline int GetOriginalSeed() const { return original_seed; } | |
/** | |
* Starts a new sequence of pseudo random numbers. | |
* | |
* @param new_seed The seed for the new sequence. | |
* A negative seed means that the random number generator gets its | |
* seed from the actual system time and the process ID. | |
**/ | |
inline void ResetSeed(const int _seed) { | |
original_seed = _seed; | |
if (_seed <= 0) { | |
int seed_time = (int) time(NULL); | |
int seed_mem = (int) ((uint64_t) this); | |
seed = seed_time ^ seed_mem; | |
} else { | |
seed = _seed; | |
} | |
if (seed < 0) seed *= -1; | |
seed %= _RAND_MSEED; | |
init(); | |
} | |
// Random Number Generation ///////////////////////////////////////////////// | |
/** | |
* Generate a double between 0.0 and 1.0 | |
* | |
* @return The pseudo random number. | |
**/ | |
inline double GetDouble() { return Get() / (double) _RAND_MBIG; } | |
/** | |
* Generate a double between 0 and a given number. | |
* | |
* @return The pseudo random number. | |
* @param max The upper bound for the random numbers (will never be returned). | |
**/ | |
inline double GetDouble(const double max) { | |
// emp_assert(max <= (double) _RAND_MBIG, max, (double) _RAND_MBIG); // Precision will be too low past this point... | |
return GetDouble() * max; | |
} | |
/** | |
* Generate a double out of a given interval. | |
* | |
* @return The pseudo random number. | |
* @param min The lower bound for the random numbers. | |
* @param max The upper bound for the random numbers (will never be returned). | |
**/ | |
inline double GetDouble(const double min, const double max) { | |
emp_assert((max-min) <= (double) _RAND_MBIG, min, max); // Precision will be too low past this point... | |
return GetDouble() * (max - min) + min; | |
} | |
/** | |
* Generate a double out of a given interval. | |
* | |
* @return The pseudo random number. | |
* @param range The upper and lower bounds for the random numbers [lower, upper) | |
**/ | |
inline double GetDouble(const Range<double> range) { | |
return GetDouble(range.GetLower(), range.GetUpper()); | |
} | |
/** | |
* Generate an uint32_t. | |
* | |
* @return The pseudo random number. | |
* @param max The upper bound for the random numbers (will never be returned). | |
**/ | |
template <typename T> | |
inline uint32_t GetUInt(const T max) { | |
emp_assert(max <= (T) _RAND_MBIG, max); // Precision will be too low past this point... | |
return static_cast<uint32_t>(GetDouble() * static_cast<double>(max)); | |
} | |
/** | |
* Generate a random 32-bit block of bits. | |
* | |
* @return The pseudo random number. | |
**/ | |
inline uint32_t GetUInt() { | |
return ( static_cast<uint32_t>(GetDouble() * 65536.0) << 16 ) | |
+ static_cast<uint32_t>(GetDouble() * 65536.0); | |
} | |
/** | |
* Generate a random 64-bit block of bits. | |
* | |
* @return The pseudo random number. | |
**/ | |
inline uint64_t GetUInt64Old() { | |
// @MAM profiled, | |
// this is faster than using RandFill | |
return ( static_cast<uint64_t>(GetUInt()) << 32 ) | |
+ static_cast<uint64_t>(GetUInt()); | |
} | |
/** | |
* Generate a random 64-bit block of bits. | |
* | |
* @return The pseudo random number. | |
**/ | |
inline uint64_t GetUInt64() { | |
uint64_t res; | |
RandFill(reinterpret_cast<unsigned char*>(&res), sizeof(res)); | |
return res; | |
} | |
/** | |
* Randomize a contiguous segment of memory. | |
**/ | |
inline void RandFillOld(unsigned char* dest, const size_t num_bytes) { | |
// go three bytes at a time because we only get | |
// _RAND_MBIG (not quite four bytes) of entropy | |
// from the generator | |
// @MAM profiled, | |
// sampling raw bytes and rejecting the region of integer space | |
// that would introduce bias is faster than rescaling using double | |
// multiplication | |
const uint32_t accept_thresh = ( | |
_RAND_MBIG - _RAND_MBIG % 16777216 /* 2^(3*8) */ | |
); | |
for (size_t byte = 0; byte + 3 < num_bytes; byte += 3) { | |
uint32_t rnd; | |
while (true) { | |
rnd = Get(); | |
if (rnd < accept_thresh) break; | |
} | |
std::memcpy(dest+byte, &rnd, 3); | |
} | |
if (num_bytes%3) { | |
uint32_t rnd; | |
while (true) { | |
rnd = Get(); | |
if (rnd < accept_thresh) break; | |
} | |
std::memcpy(dest+num_bytes-num_bytes%3, &rnd, num_bytes%3); | |
} | |
} | |
/** | |
* Randomize a contiguous segment of memory. | |
**/ | |
inline void RandFill(unsigned char* dest, const size_t num_bytes) { | |
// go three bytes at a time because we only get | |
// _RAND_MBIG (slightly more than 3 bytes) of entropy | |
// from the generator | |
for (size_t byte = 0; byte + 3 < num_bytes; byte += 3) { | |
uint32_t rnd; | |
rnd = GetDouble() * 16777216.0; /* 2^(3*8) */ | |
std::memcpy(dest+byte, &rnd, 3); | |
} | |
if (num_bytes%3) { | |
uint32_t rnd; | |
rnd = GetDouble() * 16777216.0; /* 2^(3*8) */ | |
std::memcpy(dest+num_bytes-num_bytes%3, &rnd, num_bytes%3); | |
} | |
} | |
/** | |
* Generate an uint64_t. | |
* | |
* @return The pseudo random number. | |
* @param max The upper bound for the random numbers (will never be returned). | |
* @todo this function needs to be tested and refined. | |
**/ | |
template <typename T> | |
inline uint64_t GetUInt64(const T max) { | |
if (max <= (T) _RAND_MBIG) return (uint64_t) GetUInt(max); // Don't need extra precision. | |
const double max2 = ((double) max) / (double) _RAND_MBIG; | |
emp_assert(max2 <= (T) _RAND_MBIG, max); // Precision will be too low past this point... | |
return static_cast<uint64_t>(GetDouble() * static_cast<double>(max)) | |
+ static_cast<uint64_t>(GetDouble() * static_cast<double>(max2) * _RAND_MBIG); | |
} | |
/** | |
* Generate an uint32_t out of an interval. | |
* | |
* @return The pseudo random number. | |
* @param min The lower bound for the random numbers. | |
* @param max The upper bound for the random numbers (will never be returned). | |
**/ | |
template <typename T1, typename T2> | |
inline uint32_t GetUInt(const T1 min, const T2 max) { | |
return GetUInt<uint32_t>((uint32_t) max - (uint32_t) min) + (uint32_t) min; | |
} | |
/** | |
* Generate a uint32_t out of a given interval. | |
* | |
* @return The pseudo random number. | |
* @param range The upper and lower bounds for the random numbers [lower, upper) | |
**/ | |
template <typename T> | |
inline uint32_t GetUInt(const Range<T> range) { | |
return GetUInt(range.GetLower(), range.GetUpper()); | |
} | |
/** | |
* Generate an int out of an interval. | |
* | |
* @return The pseudo random number. | |
* @param min The lower bound for the random numbers. | |
* @param max The upper bound for the random numbers (will never be returned). | |
**/ | |
inline int GetInt(const int max) { return static_cast<int>(GetUInt((uint32_t) max)); } | |
inline int GetInt(const int min, const int max) { return GetInt(max - min) + min; } | |
inline int GetInt(const Range<int> range) { return GetInt(range.GetLower(), range.GetUpper()); } | |
// Random Event Generation ////////////////////////////////////////////////// | |
/// Tests a random value [0,1) against a given probability p, and returns true of false. | |
/// @param p The probability of the result being "true". | |
inline bool P(const double p) { | |
emp_assert(p >= 0.0 && p <= 1.0, p); | |
return (Get() < (p * _RAND_MBIG)); | |
} | |
// Statistical functions //////////////////////////////////////////////////// | |
// Distributions // | |
/** | |
* Generate a random variable drawn from a unit normal distribution. | |
**/ | |
inline double GetRandNormal() { | |
// Draw from a Unit Normal Dist | |
// Using Rejection Method and saving of initial exponential random variable | |
double expRV2; | |
while (1) { | |
expRV2 = -log(GetDouble()); | |
expRV -= (expRV2-1)*(expRV2-1)/2; | |
if (expRV > 0) break; | |
expRV = -log(GetDouble()); | |
} | |
if (P(.5)) return expRV2; | |
return -expRV2; | |
} | |
/** | |
* Generate a random variable drawn from a distribution with given | |
* mean and standard deviation. | |
**/ | |
inline double GetRandNormal(const double mean, const double std) { return mean + GetRandNormal() * std; } | |
/** | |
* Generate a random variable drawn from a Poisson distribution. | |
**/ | |
inline uint32_t GetRandPoisson(const double n, double p) { | |
emp_assert(p >= 0.0 && p <= 1.0, p); | |
// Optimizes for speed and calculability using symetry of the distribution | |
if (p > .5) return (uint32_t)n - GetRandPoisson(n * (1 - p)); | |
else return GetRandPoisson(n * p); | |
} | |
/** | |
* Generate a random variable drawn from a Poisson distribution. | |
* | |
* @param mean The mean of the distribution. | |
**/ | |
inline uint32_t GetRandPoisson(const double mean) { | |
// Draw from a Poisson Dist with mean; if cannot calculate, return UINT_MAX. | |
// Uses Rejection Method | |
const double a = exp(-mean); | |
if (a <= 0) return UINT_MAX; // cannot calculate, so return UINT_MAX | |
uint32_t k = 0; | |
double u = GetDouble(); | |
while (u >= a) { | |
u *= GetDouble(); | |
++k; | |
} | |
return k; | |
} | |
/** | |
* Generate a random variable drawn from a Binomial distribution. | |
* | |
* This function is exact, but slow. | |
* @see Random::GetApproxRandBinomial | |
* @see emp::Binomial in source/tools/Binomial.h | |
**/ | |
inline uint32_t GetFullRandBinomial(const double n, const double p) { // Exact | |
emp_assert(p >= 0.0 && p <= 1.0, p); | |
emp_assert(n >= 0.0, n); | |
// Actually try n Bernoulli events, each with probability p | |
uint32_t k = 0; | |
for (uint32_t i = 0; i < n; ++i) if (P(p)) k++; | |
return k; | |
} | |
/** | |
* Generate a random variable drawn from a Binomial distribution. | |
* | |
* This function is faster than @ref Random::GetFullRandBinomial(), but | |
* uses some approximations. Note that for repeated calculations with | |
* the same n and p, the Binomial class provides a much faster and more | |
* exact interface. | |
* | |
* @see Random::GetFullRandBinomial | |
* @see emp::Binomial in source/tools/Binomial.h | |
**/ | |
inline uint32_t GetApproxRandBinomial(const double n, const double p) { // Approx | |
emp_assert(p >= 0.0 && p <= 1.0, p); | |
emp_assert(n >= 0.0, n); | |
// Approximate Binomial if appropriate | |
// if np(1-p) is large, we might be tempted to use a Normal approx, but it is giving poor results. | |
// if (n * p * (1 - p) >= _BINOMIAL_TO_NORMAL) { | |
// return static_cast<uint32_t>(GetRandNormal(n * p, n * p * (1 - p)) + 0.5); | |
// } | |
// If n is large, use a Poisson approx | |
if (n >= _BINOMIAL_TO_POISSON) { | |
uint32_t k = GetRandPoisson(n, p); | |
if (k < UINT_MAX) return k; // if approx worked | |
} | |
// otherwise, actually generate the randBinomial | |
return GetFullRandBinomial(n, p); | |
} | |
/** | |
* By default GetRandBinomial calls the full (non-approximation) version. | |
* | |
* Note that if approximations are okay, they can create a big speedup | |
* for n > 1000. | |
* | |
* @see Random::GetFullRandBinomial | |
* @see Random::GetApproxRandBinomial | |
* @see emp::Binomial in source/tools/Binomial.h | |
**/ | |
inline uint32_t GetRandBinomial(const double n, const double p) { | |
return GetFullRandBinomial(n,p); | |
} | |
}; | |
/// This is an adaptor to make Random behave like a proper STL random number generator. | |
struct RandomStdAdaptor { | |
typedef int argument_type; | |
typedef int result_type; | |
RandomStdAdaptor(Random& rng) : _rng(rng) { } | |
int operator()(int n) { return _rng.GetInt(n); } | |
Random& _rng; | |
}; | |
/// Draw a sample (with replacement) from an input range, copying to the output range. | |
template <typename ForwardIterator, typename OutputIterator, typename RNG> | |
void sample_with_replacement(ForwardIterator first, ForwardIterator last, OutputIterator ofirst, OutputIterator olast, RNG rng) { | |
std::size_t range = std::distance(first, last); | |
while(ofirst != olast) { | |
*ofirst = *(first+rng(range)); | |
++ofirst; | |
} | |
} | |
} // END emp namespace | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type,timing | |
old,3332 | |
new,3310 | |
old,3064 | |
new,3324 | |
old,3267 | |
new,3185 | |
old,2694 | |
new,2830 | |
old,2574 | |
new,2661 | |
old,2542 | |
new,2787 | |
old,2475 | |
new,2698 | |
old,2558 | |
new,3006 | |
old,2640 | |
new,2693 | |
old,2531 | |
new,2719 | |
old,2543 | |
new,2722 | |
old,2505 | |
new,2741 | |
old,2522 | |
new,2734 | |
old,2426 | |
new,2835 | |
old,2796 | |
new,2869 | |
old,2544 | |
new,2705 | |
old,2474 | |
new,2743 | |
old,2528 | |
new,2752 | |
old,2477 | |
new,2721 | |
old,2505 | |
new,2498 | |
old,1789 | |
new,2595 | |
old,1890 | |
new,2709 | |
old,1853 | |
new,2228 | |
old,1862 | |
new,2285 | |
old,2020 | |
new,2446 | |
old,1848 | |
new,2249 | |
old,1830 | |
new,2756 | |
old,2064 | |
new,2804 | |
old,2230 | |
new,2309 | |
old,1771 | |
new,2268 | |
old,1844 | |
new,2268 | |
old,2182 | |
new,2416 | |
old,2614 | |
new,3117 | |
old,1893 | |
new,2231 | |
old,1801 | |
new,2237 | |
old,2014 | |
new,2537 | |
old,1876 | |
new,2857 | |
old,2832 | |
new,2524 | |
old,1933 | |
new,2306 | |
old,2032 | |
new,2261 | |
old,1802 | |
new,2246 | |
old,2459 | |
new,3090 | |
old,2455 | |
new,2236 | |
old,1953 | |
new,2255 | |
old,1902 | |
new,2292 | |
old,2172 | |
new,2942 | |
old,2499 | |
new,2501 | |
old,1930 | |
new,2294 | |
old,1921 | |
new,2474 | |
old,2132 | |
new,2829 | |
old,2678 | |
new,2919 | |
old,1828 | |
new,2384 | |
old,2034 | |
new,2389 | |
old,2179 | |
new,2654 | |
old,1992 | |
new,2647 | |
old,1969 | |
new,2480 | |
old,1996 | |
new,2609 | |
old,2025 | |
new,2668 | |
old,2867 | |
new,3075 | |
old,1958 | |
new,2591 | |
old,2023 | |
new,2454 | |
old,2085 | |
new,3001 | |
old,2981 | |
new,2689 | |
old,2080 | |
new,2409 | |
old,1993 | |
new,2554 | |
old,2065 | |
new,2859 | |
old,2870 | |
new,2969 | |
old,2008 | |
new,2528 | |
old,2061 | |
new,2592 | |
old,2448 | |
new,2768 | |
old,2065 | |
new,2546 | |
old,1995 | |
new,2563 | |
old,2215 | |
new,2636 | |
old,2491 | |
new,2704 | |
old,2191 | |
new,2815 | |
old,1970 | |
new,2616 | |
old,2324 | |
new,2648 | |
old,2126 | |
new,2859 | |
old,2980 | |
new,2895 | |
old,2056 | |
new,2791 | |
old,2001 | |
new,2563 | |
old,2117 | |
new,2817 | |
old,2689 | |
new,2914 | |
old,2124 | |
new,2511 | |
old,2109 | |
new,2620 | |
old,2224 | |
new,3043 | |
old,2161 | |
new,2682 | |
old,2020 | |
new,2610 | |
old,2192 | |
new,2657 | |
old,2747 | |
new,3061 | |
old,3001 | |
new,2788 | |
old,2060 | |
new,2645 | |
old,2174 | |
new,2612 | |
old,2739 | |
new,3823 | |
old,2534 | |
new,2739 | |
old,2067 | |
new,2670 | |
old,2075 | |
new,2891 | |
old,2244 | |
new,2724 | |
old,2055 | |
new,2708 | |
old,2023 | |
new,2580 | |
old,2187 | |
new,2611 | |
old,2235 | |
new,2661 | |
old,2165 | |
new,2692 | |
old,2216 | |
new,3014 | |
old,2236 | |
new,2755 | |
old,2067 | |
new,2584 | |
old,2077 | |
new,2648 | |
old,2215 | |
new,2722 | |
old,2411 | |
new,2610 | |
old,2227 | |
new,2968 | |
old,2179 | |
new,2920 | |
old,2067 | |
new,2563 | |
old,2258 | |
new,2536 | |
old,2148 | |
new,2619 | |
old,2147 | |
new,2787 | |
old,2698 | |
new,2716 | |
old,2329 | |
new,2526 | |
old,17965 | |
new,3255 | |
old,3012 | |
new,3293 | |
old,3095 | |
new,3429 | |
old,3159 | |
new,3482 | |
old,3191 | |
new,3460 | |
old,3210 | |
new,3387 | |
old,3230 | |
new,3440 | |
old,3116 | |
new,3384 | |
old,3249 | |
new,3389 | |
old,2948 | |
new,3287 | |
old,2932 | |
new,3402 | |
old,3044 | |
new,3234 | |
old,3139 | |
new,3396 | |
old,2487 | |
new,3275 | |
old,2274 | |
new,3117 | |
old,2193 | |
new,2640 | |
old,2504 | |
new,2815 | |
old,2550 | |
new,2788 | |
old,2016 | |
new,2519 | |
old,2089 | |
new,3012 | |
old,2522 | |
new,3150 | |
old,2146 | |
new,2437 | |
old,2095 | |
new,2922 | |
old,2713 | |
new,3157 | |
old,2524 | |
new,2458 | |
old,2091 | |
new,2749 | |
old,2502 | |
new,2679 | |
old,2611 | |
new,2567 | |
old,2066 | |
new,2587 | |
old,2142 | |
new,2692 | |
old,2191 | |
new,3056 | |
old,3055 | |
new,2834 | |
old,2130 | |
new,2675 | |
old,2114 | |
new,2662 | |
old,2080 | |
new,3078 | |
old,3086 | |
new,2796 | |
old,2129 | |
new,2707 | |
old,2089 | |
new,2636 | |
old,2823 | |
new,3502 | |
old,2360 | |
new,2609 | |
old,2065 | |
new,2598 | |
old,2122 | |
new,2717 | |
old,2817 | |
new,3404 | |
old,2409 | |
new,2556 | |
old,2143 | |
new,2841 | |
old,3057 | |
new,3288 | |
old,2265 | |
new,2533 | |
old,2126 | |
new,2757 | |
old,3037 | |
new,3469 | |
old,2166 | |
new,2548 | |
old,2064 | |
new,2629 | |
old,2725 | |
new,3250 | |
old,2595 | |
new,2511 | |
old,2143 | |
new,2582 | |
old,2125 | |
new,2736 | |
old,2697 | |
new,2881 | |
old,2414 | |
new,2559 | |
old,2127 | |
new,2736 | |
old,2096 | |
new,2849 | |
old,2100 | |
new,2609 | |
old,2235 | |
new,2634 | |
old,2309 | |
new,3119 | |
old,3182 | |
new,2679 | |
old,2148 | |
new,2719 | |
old,2142 | |
new,2736 | |
old,2425 | |
new,2633 | |
old,2238 | |
new,3261 | |
old,2838 | |
new,2778 | |
old,2238 | |
new,2572 | |
old,2182 | |
new,2695 | |
old,2218 | |
new,3058 | |
old,2277 | |
new,2861 | |
old,2119 | |
new,2703 | |
old,2254 | |
new,2646 | |
old,2257 | |
new,2764 | |
old,2435 | |
new,2702 | |
old,2236 | |
new,2605 | |
old,2235 | |
new,2685 | |
old,2251 | |
new,2662 | |
old,2526 | |
new,2753 | |
old,2413 | |
new,2533 | |
old,2326 | |
new,2567 | |
old,2100 | |
new,2787 | |
old,2721 | |
new,2981 | |
old,2364 | |
new,2563 | |
old,2098 | |
new,2723 | |
old,2276 | |
new,3092 | |
old,2188 | |
new,2715 | |
old,2288 | |
new,2547 | |
old,2187 | |
new,2689 | |
old,2351 | |
new,2797 | |
old,2764 | |
new,3311 | |
old,2373 | |
new,2591 | |
old,2410 | |
new,2943 | |
old,2232 | |
new,2918 | |
old,2408 | |
new,2837 | |
old,2353 | |
new,2662 | |
old,2245 | |
new,2528 | |
old,2123 | |
new,2955 | |
old,2277 | |
new,2965 | |
old,2213 | |
new,2647 | |
old,2140 | |
new,2725 | |
old,2233 | |
new,3110 | |
old,2619 | |
new,2890 | |
old,2073 | |
new,2703 | |
old,2148 | |
new,2719 | |
old,2362 | |
new,2910 | |
old,2820 | |
new,3343 | |
old,2002 | |
new,2616 | |
old,2256 | |
new,2828 | |
old,2101 | |
new,2965 | |
old,2260 | |
new,2966 | |
old,2212 | |
new,2710 | |
old,2254 | |
new,2575 | |
old,2158 | |
new,2928 | |
old,2415 | |
new,2935 | |
old,2227 | |
new,3372 | |
old,2389 | |
new,2706 | |
old,2205 | |
new,3227 | |
old,2795 | |
new,3172 | |
old,1993 | |
new,2625 | |
old,2127 | |
new,2762 | |
old,2444 | |
new,2780 | |
old,2236 | |
new,3250 | |
old,2099 | |
new,2803 | |
old,2127 | |
new,2811 | |
old,2035 | |
new,2941 | |
old,2355 | |
new,2916 | |
old,2119 | |
new,2844 | |
old,2121 | |
new,2642 | |
old,2170 | |
new,3031 | |
old,2597 | |
new,2804 | |
old,2129 | |
new,2691 | |
old,2184 | |
new,2726 | |
old,2374 | |
new,2912 | |
old,2621 | |
new,2914 | |
old,2022 | |
new,2644 | |
old,2169 | |
new,2747 | |
old,2360 | |
new,2905 | |
old,2394 | |
new,2866 | |
old,2085 | |
new,2613 | |
old,2225 | |
new,2720 | |
old,2092 | |
new,2713 | |
old,3097 | |
new,3453 | |
old,1996 | |
new,2772 | |
old,2017 | |
new,2601 | |
old,2137 | |
new,3209 | |
old,3078 | |
new,2857 | |
old,2108 | |
new,2696 | |
old,2127 | |
new,2711 | |
old,2601 | |
new,3397 | |
old,2594 | |
new,2607 | |
old,2130 | |
new,2641 | |
old,2253 | |
new,2788 | |
old,2641 | |
new,3022 | |
old,2343 | |
new,2604 | |
old,2146 | |
new,2726 | |
old,2206 | |
new,2634 | |
old,2212 | |
new,3005 | |
old,2218 | |
new,2927 | |
old,2032 | |
new,2754 | |
old,1987 | |
new,2650 | |
old,2211 | |
new,3030 | |
old,2458 | |
new,2800 | |
old,2030 | |
new,2692 | |
old,2226 | |
new,2719 | |
old,2325 | |
new,3297 | |
old,3089 | |
new,2612 | |
old,2110 | |
new,2601 | |
old,2162 | |
new,2746 | |
old,2109 | |
new,2800 | |
old,3056 | |
new,3167 | |
old,1994 | |
new,2617 | |
old,2239 | |
new,2657 | |
old,2053 | |
new,3052 | |
old,3216 | |
new,2956 | |
old,2075 | |
new,2658 | |
old,2119 | |
new,2703 | |
old,2130 | |
new,3183 | |
old,3176 | |
new,2798 | |
old,2087 | |
new,2723 | |
old,2133 | |
new,2780 | |
old,2964 | |
new,3299 | |
old,3053 | |
new,2761 | |
old,2098 | |
new,2759 | |
old,2592 | |
new,3227 | |
old,2527 | |
new,2948 | |
old,2039 | |
new,2671 | |
old,2282 | |
new,2828 | |
old,2121 | |
new,2784 | |
old,2416 | |
new,2948 | |
old,2452 | |
new,2782 | |
old,2045 | |
new,2562 | |
old,2196 | |
new,3090 | |
old,2384 | |
new,2989 | |
old,2464 | |
new,2627 | |
old,2088 | |
new,2727 | |
old,2163 | |
new,3130 | |
old,2366 | |
new,2730 | |
old,2048 | |
new,2709 | |
old,2130 | |
new,2735 | |
old,2227 | |
new,3068 | |
old,2416 | |
new,2872 | |
old,2054 | |
new,2717 | |
old,2295 | |
new,2679 | |
old,2281 | |
new,2826 | |
old,2458 | |
new,2916 | |
old,2186 | |
new,2593 | |
old,2142 | |
new,2700 | |
old,2103 | |
new,2927 | |
old,2556 | |
new,2980 | |
old,2307 | |
new,2697 | |
old,2136 | |
new,2727 | |
old,2189 | |
new,3040 | |
old,2674 | |
new,3125 | |
old,2050 | |
new,2645 | |
old,2101 | |
new,2755 | |
old,2336 | |
new,3022 | |
old,2207 | |
new,2672 | |
old,2273 | |
new,2548 | |
old,2298 | |
new,2807 | |
old,2228 | |
new,2759 | |
old,2637 | |
new,2750 | |
old,2433 | |
new,2572 | |
old,2522 | |
new,2673 | |
old,2165 | |
new,2799 | |
old,2984 | |
new,3308 | |
old,2093 | |
new,2644 | |
old,2188 | |
new,2699 | |
old,2204 | |
new,3110 | |
old,2745 | |
new,2854 | |
old,2104 | |
new,2688 | |
old,2201 | |
new,2830 | |
old,2156 | |
new,3137 | |
old,2638 | |
new,2887 | |
old,2201 | |
new,2694 | |
old,2285 | |
new,2850 | |
old,2131 | |
new,2895 | |
old,2337 | |
new,2960 | |
old,2306 | |
new,2848 | |
old,2379 | |
new,2742 | |
old,2243 | |
new,3007 | |
old,3150 | |
new,3029 | |
old,2097 | |
new,2644 | |
old,2171 | |
new,2773 | |
old,2306 | |
new,3144 | |
old,2580 | |
new,2661 | |
old,2054 | |
new,2731 | |
old,2279 | |
new,2827 | |
old,2652 | |
new,2935 | |
old,2208 | |
new,2895 | |
old,2199 | |
new,2729 | |
old,2512 | |
new,2659 | |
old,2200 | |
new,3037 | |
old,2209 | |
new,3153 | |
old,2440 | |
new,2622 | |
old,2204 | |
new,2719 | |
old,2373 | |
new,3114 | |
old,2314 | |
new,2801 | |
old,2201 | |
new,2738 | |
old,2176 | |
new,2888 | |
old,2625 | |
new,2973 | |
old,2586 | |
new,2579 | |
old,2185 | |
new,2724 | |
old,2727 | |
new,3170 | |
old,2999 | |
new,2844 | |
old,2165 | |
new,2708 | |
old,2409 | |
new,2839 | |
old,2796 | |
new,3453 | |
old,2221 | |
new,2667 | |
old,2312 | |
new,2830 | |
old,2723 | |
new,2750 | |
old,2675 | |
new,2564 | |
old,2454 | |
new,2855 | |
old,2420 | |
new,3330 | |
old,2699 | |
new,2554 | |
old,2457 | |
new,2875 | |
old,2276 | |
new,2579 | |
old,2201 | |
new,2677 | |
old,2249 | |
new,2637 | |
old,2142 | |
new,3353 | |
old,2922 | |
new,2611 | |
old,2179 | |
new,2702 | |
old,2636 | |
new,2721 | |
old,2311 | |
new,2694 | |
old,2186 | |
new,3327 | |
old,3034 | |
new,2586 | |
old,2131 | |
new,2699 | |
old,2416 | |
new,2719 | |
old,2454 | |
new,3227 | |
old,3137 | |
new,2838 | |
old,2139 | |
new,2801 | |
old,2288 | |
new,2847 | |
old,2349 | |
new,3525 | |
old,2562 | |
new,2713 | |
old,2190 | |
new,2890 | |
old,2126 | |
new,2666 | |
old,2712 | |
new,2857 | |
old,2518 | |
new,2690 | |
old,2142 | |
new,2732 | |
old,2154 | |
new,2826 | |
old,2965 | |
new,3499 | |
old,2209 | |
new,2649 | |
old,2207 | |
new,2918 | |
old,2562 | |
new,2840 | |
old,2566 | |
new,2586 | |
old,2189 | |
new,2770 | |
old,2696 | |
new,3267 | |
old,2620 | |
new,2617 | |
old,2128 | |
new,2672 | |
old,2242 | |
new,2910 | |
old,2938 | |
new,3058 | |
old,2083 | |
new,2580 | |
old,2257 | |
new,2729 | |
old,2204 | |
new,2806 | |
old,2140 | |
new,2735 | |
old,2381 | |
new,2686 | |
old,2153 | |
new,2724 | |
old,2139 | |
new,2708 | |
old,2741 | |
new,2787 | |
old,2572 | |
new,2546 | |
old,2181 | |
new,2716 | |
old,2169 | |
new,2836 | |
old,3091 | |
new,3560 | |
old,2092 | |
new,2617 | |
old,2202 | |
new,2722 | |
old,2424 | |
new,3234 | |
old,3000 | |
new,3124 | |
old,2141 | |
new,2649 | |
old,2241 | |
new,2624 | |
old,2281 | |
new,2630 | |
old,3075 | |
new,3206 | |
old,2257 | |
new,2632 | |
old,2266 | |
new,2644 | |
old,2181 | |
new,3039 | |
old,3166 | |
new,2923 | |
old,2225 | |
new,2597 | |
old,2208 | |
new,2713 | |
old,2210 | |
new,3099 | |
old,2189 | |
new,2906 | |
old,2194 | |
new,2684 | |
old,2241 | |
new,2825 | |
old,2474 | |
new,3226 | |
old,2152 | |
new,2892 | |
old,2054 | |
new,2759 | |
old,2359 | |
new,2737 | |
old,2180 | |
new,2968 | |
old,2357 | |
new,2845 | |
old,2273 | |
new,2734 | |
old,2317 | |
new,2678 | |
old,2237 | |
new,3072 | |
old,2430 | |
new,2915 | |
old,2252 | |
new,2645 | |
old,2254 | |
new,2768 | |
old,2780 | |
new,2957 | |
old,2956 | |
new,2753 | |
old,2116 | |
new,2685 | |
old,2195 | |
new,2909 | |
old,2785 | |
new,3009 | |
old,2579 | |
new,2546 | |
old,2210 | |
new,2867 | |
old,2468 | |
new,2671 | |
old,2693 | |
new,3417 | |
old,2266 | |
new,2817 | |
old,2598 | |
new,2644 | |
old,2241 | |
new,2700 | |
old,3054 | |
new,3475 | |
old,2153 | |
new,2610 | |
old,2155 | |
new,2715 | |
old,3022 | |
new,3308 | |
old,2766 | |
new,2659 | |
old,2205 | |
new,3014 | |
old,2298 | |
new,2941 | |
old,2331 | |
new,3053 | |
old,2222 | |
new,2768 | |
old,3030 | |
new,3522 | |
old,2314 | |
new,2637 | |
old,2200 | |
new,2759 | |
old,3110 | |
new,3462 | |
old,2161 | |
new,2629 | |
old,2195 | |
new,2770 | |
old,3093 | |
new,3518 | |
old,2274 | |
new,2586 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment