Skip to content

Instantly share code, notes, and snippets.

@eyalroz
Last active April 5, 2020 23:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eyalroz/ebea248b41f0b32d4e92109c4e9233e8 to your computer and use it in GitHub Desktop.
Save eyalroz/ebea248b41f0b32d4e92109c4e9233e8 to your computer and use it in GitHub Desktop.
benchmarks for stackoverflow question 61047308
#include <geiger/geiger.h>
#include <cmath>
#include <cstdlib>
#include <string>
#include <iostream>
#include <random>
namespace aliberro {
float getPlaces(int x)
{
unsigned char p=0;
while(x!=0)
{
x/=10;
p++;
}
float pow10[] = {1.0f,10.0f,100.0f,1000.0f,10000.0f,100000.0f};//don't need more
return pow10[p];
}
} // namespace aliberro
namespace tarek {
inline uint32_t digits_10(uint32_t x) {
return 1u
+ (x >= 10u)
+ (x >= 100u)
+ (x >= 1000u)
+ (x >= 10000u)
+ (x >= 100000u)
+ (x >= 1000000u)
+ (x >= 10000000u)
+ (x >= 100000000u)
+ (x >= 1000000000u)
;
}
inline uint64_t pow_10(uint32_t exp) {
uint64_t res = 1;
while(exp--) {
res *= 10u;
}
return res;
}
} // namespace tarek
int main() {
geiger::init();
geiger::suite<> s;
std::random_device rd;
// Choose a random mean between 1 and 6
std::default_random_engine engine(rd());
std::uniform_int_distribution<int> uniform_dist {};
std::vector<int> samples;
constexpr const std::size_t num_samples {1lu << 11};
samples.reserve(num_samples);
std::generate_n(
std::back_inserter(samples),
num_samples,
[&]() { return uniform_dist(engine); }
);
std::size_t sample_index {0};
s.add("cache warmup", [&]() {
auto x = samples[sample_index++];
auto y = samples[sample_index++];
sample_index = sample_index % num_samples;
});
s.add("@aliberro's conversion v2", [&]() {
auto x = samples[sample_index++];
auto y = samples[sample_index++];
sample_index = sample_index % num_samples;
if(y == 0) return (float) x;
float sign = x != 0 ? x/abs(x) : 1;
float tm = abs(x), tm2 = abs(y);
tm2 /= aliberro::getPlaces(y);
return (tm+tm2)*sign;
});
s.add("@3Dave's conversion", [&]() {
auto x = samples[sample_index++];
auto y = samples[sample_index++];
sample_index = sample_index % num_samples;
if (0==y) { return (float) x; }
float den = std::pow(10,std::floor(std::log10(y)+1));
return float(x + y / den);
});
s.add("@einpoklum's conversion", [&]() {
auto x = samples[sample_index++];
auto y = samples[sample_index++];
sample_index = sample_index % num_samples;
float fy (y);
if (y == 0) { return float(x); }
if (y > 1e9) { return float(x + fy * 1e-10f); }
if (y > 1e8) { return float(x + fy * 1e-9f); }
if (y > 1e7) { return float(x + fy * 1e-8f); }
if (y > 1e6) { return float(x + fy * 1e-7f); }
if (y > 1e5) { return float(x + fy * 1e-6f); }
if (y > 1e4) { return float(x + fy * 1e-5f); }
if (y > 1e3) { return float(x + fy * 1e-4f); }
if (y > 1e2) { return float(x + fy * 1e-3f); }
if (y > 1e1) { return float(x + fy * 1e-2f); }
return float(x + fy * 1e-1f);
});
s.add("@Ripi2's conversion", [&]() {
auto x = samples[sample_index++];
auto y = samples[sample_index++];
sample_index = sample_index % num_samples;
double dp = (double) y;
while (dp > 1) { dp /= 10; }
return (float)(x + dp);
});
s.add("@TarekDakhran's conversion", [&]() {
auto x = samples[sample_index++];
auto y = samples[sample_index++];
sample_index = sample_index % num_samples;
return x + static_cast<float>(y) / tarek::pow_10(tarek::digits_10(y));
});
s.set_printer<geiger::printer::console<>>();
s.run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment