Project

General

Profile

Download (6.21 KB) Statistics
| Branch: | Tag: | Revision:
#include <charconv>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <random>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include "fixed.h"

// g++ -std=c++17 -O3 parse.cc -o parse

void genRandomNumStrings(
uint32_t number,
std::vector<std::string>& values,
uint64_t seed)
{
values.clear();
std::random_device dev;
//~ std::mt19937 rng(dev());
std::mt19937 rng;
rng.seed(seed);
std::uniform_int_distribution<std::mt19937::result_type> numDigits(1, 18);
std::uniform_int_distribution<std::mt19937::result_type> digits(0, 9);
for (uint32_t idx = 0; idx < number; ++idx)
{
std::ostringstream output;
// Generate random whole number digits
for (uint32_t wholeIdx = 0; wholeIdx < numDigits(rng); ++wholeIdx)
{
output << digits(rng);
}
output << ".";
// Generate random fractional number digits
for (uint32_t fracIdx = 0; fracIdx < numDigits(rng); ++fracIdx)
{
output << digits(rng);
}
values.emplace_back(output.str());
//~ std::cout << "VAL: " << values.back() << std::endl;
}
}

int main(int argc, char** argv)
{
std::cout << "Long Double Parse Test Util\n" << std::endl;
if (argc < 3)
{
std::cerr << "ERROR: not enough arguments" << std::endl;
return -1;
}
uint32_t parseType = std::strtoul(argv[1], nullptr, 10);
uint32_t numRandomStrings = std::strtoul(argv[2], nullptr, 10);
uint64_t seed = 0xDEADBEEF;
if (argc > 3)
{
seed = std::strtoull(argv[3], nullptr, 0);
}
std::vector<std::string> values;
{
auto start = std::chrono::system_clock::now();
genRandomNumStrings(numRandomStrings, values, seed);
auto end = std::chrono::system_clock::now();
auto diff = end - start;
std::cout << "Time to generate " << numRandomStrings << " values: "
<< std::chrono::duration <double, std::milli>(diff).count()
<< " ms" << std::endl;
}
long double value = 0.0;
fixed_64_64 fvalue;
//~ fixed_128_128 f128value;
// 0) strtold()
if (parseType == 0)
{
std::cout << "Parse type 0: std::strtold()" << std::endl;
auto start = std::chrono::system_clock::now();
for (auto& strValue : values)
{
value = std::strtold(strValue.c_str(), nullptr);
//~ std::cout << "In: " << strValue << " -- Out: " << value << std::endl;
}
auto end = std::chrono::system_clock::now();
auto diff = end - start;
std::cout << "Total parse time: "
<< std::chrono::duration <double, std::milli>(diff).count()
<< " ms" << std::endl;
}
// 1) stold()
else if (parseType == 1)
{
std::cout << "Parse type 1: std::stold()" << std::endl;
auto start = std::chrono::system_clock::now();
for (auto& strValue : values)
{
value = std::stold(strValue.c_str(), nullptr);
//~ std::cout << "In: " << strValue << " -- Out: " << value << std::endl;
}
auto end = std::chrono::system_clock::now();
auto diff = end - start;
std::cout << "Total parse time: "
<< std::chrono::duration <double, std::milli>(diff).count()
<< " ms" << std::endl;
}
// 2) istringstream
else if (parseType == 2)
{
std::cout << "Parse type 2: std::istringstream" << std::endl;
auto start = std::chrono::system_clock::now();
std::istringstream stream;
for (auto& strValue : values)
{
stream.clear();
stream.str(strValue);
stream >> value;
//~ std::cout << "In: " << strValue << " -- Out: " << value << std::endl;
}
auto end = std::chrono::system_clock::now();
auto diff = end - start;
std::cout << "Total parse time: "
<< std::chrono::duration <double, std::milli>(diff).count()
<< " ms" << std::endl;
}
// 3)
else if (parseType == 3)
{
std::cout << "Parse type 3: fixed_64_64" << std::endl;
auto start = std::chrono::system_clock::now();
for (auto& strValue : values)
{
fvalue.parse(strValue.c_str());
//~ std::cout << "In: " << strValue << " -- Out: " << fvalue << std::endl;
}
auto end = std::chrono::system_clock::now();
auto diff = end - start;
std::cout << "Total parse time: "
<< std::chrono::duration <double, std::milli>(diff).count()
<< " ms" << std::endl;
}
#if 0 // This needs >= gcc 11
// 4) from_chars()
else if (parseType == 4)
{
std::cout << "Parse type 4: std::from_chars()" << std::endl;
auto start = std::chrono::system_clock::now();
for (auto& strValue : values)
{
std::from_chars(strValue.begin(), strValue.end(),
value, std::chars_format::general);
//~ std::cout << "In: " << strValue << " -- Out: " << value << std::endl;
}
auto end = std::chrono::system_clock::now();
auto diff = end - start;
std::cout << "Total parse time: "
<< std::chrono::duration <double, std::milli>(diff).count()
<< " ms" << std::endl;
}
#endif
#if 0
// 5)
else if (parseType == 5)
{
std::cout << "Parse type 5: fixed_128_128" << std::endl;
auto start = std::chrono::system_clock::now();
for (auto& strValue : values)
{
f128value.parse(strValue.c_str());
std::cout << "In: " << strValue << " -- Out: " << f128value << std::endl;
}
auto end = std::chrono::system_clock::now();
auto diff = end - start;
std::cout << "Total parse time: "
<< std::chrono::duration <double, std::milli>(diff).count()
<< " ms" << std::endl;
}
#endif
else
{
std::cerr << "ERROR: invalid parse type: " << parseType << std::endl;
return -2;
}
return 0;
}
(8-8/9)