Skip to content

Instantly share code, notes, and snippets.

@miguelmartin75
Last active August 29, 2015 14:02
Show Gist options
  • Save miguelmartin75/d9b583d4445b319601ab to your computer and use it in GitHub Desktop.
Save miguelmartin75/d9b583d4445b319601ab to your computer and use it in GitHub Desktop.
add vs lookup table
#include <chrono>
#include <cstdint>
#include <iostream>
#include <random>
#include <sstream>
using namespace std;
typedef std::chrono::microseconds time_unit;
static const std::string time_unit_suffix{"us"};
time_unit getTimeNow()
{
auto t = chrono::high_resolution_clock::now();
return std::chrono::duration_cast<time_unit>(t.time_since_epoch());
}
uint32_t lwan_test(uint64_t value, char *buffer)
{
char *p = buffer + numeric_limits<uint64_t>::digits10 - 1;
*p = '\0';
do {
*--p = (char) ('0' + value % 10);
} while (value /= 10);
return (unsigned int) (numeric_limits<uint64_t>::digits10 -
(unsigned int) (p - buffer) - 1);
}
uint32_t lwan_lut_test(uint64_t value, char *buffer)
{
char *p = buffer + numeric_limits<uint64_t>::digits10 - 1;
*p = '\0';
do {
*--p = "0123456789"[value % 10];
} while (value /= 10);
return (unsigned int) (numeric_limits<uint64_t>::digits10 -
(unsigned int) (p - buffer) - 1);
}
static void strreverse(char* begin, char* end)
{
char aux;
while (end > begin)
aux = *end, *end-- = *begin, *begin++ = aux;
}
template <typename F>
time_unit test(const vector<uint64_t>& vector, F func)
{
char buf[3 * sizeof(uint64_t)];
int checksum = 0;
auto start = getTimeNow();
for (size_t run = 0; run < 50; run++) {
for (uint64_t value : vector)
checksum += func(value, buf);
}
auto end = getTimeNow();
return end - start;
}
void print_results(std::string name, time_unit time)
{
std::cout << name << ": took " << time.count() << ' ' << time_unit_suffix << '\n';
}
int main(int argc, char* argv[])
{
mt19937 random_engine;
vector<uint64_t> vector(1000000);
random_engine.seed(0xdeadbeef);
for (auto power = 100000000000L; power >= 1; power /= 10) {
uniform_int_distribution<uint64_t> distribution(0, power);
for (auto i = vector.size(); i != 0; i--)
vector[i] = distribution(random_engine);
cout << "For values in interval [0," << power << "]:\n";
auto t1 = test(vector, lwan_test);
auto t2 = test(vector, lwan_lut_test);
print_results("lawn_test_add", t1);
print_results("lwan_lut_test", t2);
auto diff = (t2 - t1).count();
auto percentageDiff = static_cast<double>(diff) / (t1 + t2).count();
std::cout << "add was: " << diff << " " << time_unit_suffix << " ";
std::cout << (diff < 0 ? "slower" : "faster");
std::cout << " (" << 100 * percentageDiff << "% difference)\n";
cout << "\n";
}
return 0;
}
$ c++ --version
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
$ c++ inttostr.cpp -std=c++11 -O3 -o inttostr
$ ./inttostr
For values in interval [0,100000000000]:
lawn_test_add: took 1180147 us
lwan_lut_test: took 1387113 us
add was: 206966 us faster (8.06175% difference)
For values in interval [0,10000000000]:
lawn_test_add: took 1100406 us
lwan_lut_test: took 1232800 us
add was: 132394 us faster (5.67434% difference)
For values in interval [0,1000000000]:
lawn_test_add: took 962111 us
lwan_lut_test: took 1039763 us
add was: 77652 us faster (3.87897% difference)
For values in interval [0,100000000]:
lawn_test_add: took 832761 us
lwan_lut_test: took 918867 us
add was: 86106 us faster (4.91577% difference)
For values in interval [0,10000000]:
lawn_test_add: took 759096 us
lwan_lut_test: took 822768 us
add was: 63672 us faster (4.02512% difference)
For values in interval [0,1000000]:
lawn_test_add: took 606999 us
lwan_lut_test: took 680095 us
add was: 73096 us faster (5.67915% difference)
For values in interval [0,100000]:
lawn_test_add: took 498602 us
lwan_lut_test: took 538036 us
add was: 39434 us faster (3.80403% difference)
For values in interval [0,10000]:
lawn_test_add: took 408179 us
lwan_lut_test: took 431154 us
add was: 22975 us faster (2.73729% difference)
For values in interval [0,1000]:
lawn_test_add: took 298869 us
lwan_lut_test: took 335538 us
add was: 36669 us faster (5.78004% difference)
For values in interval [0,100]:
lawn_test_add: took 228339 us
lwan_lut_test: took 225532 us
add was: -2807 us slower (-0.618458% difference)
For values in interval [0,10]:
lawn_test_add: took 133550 us
lwan_lut_test: took 136035 us
add was: 2485 us faster (0.921787% difference)
For values in interval [0,1]:
lawn_test_add: took 105890 us
lwan_lut_test: took 123110 us
add was: 17220 us faster (7.51965% difference)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment