mirror of
https://github.com/fastfloat/fast_float.git
synced 2026-02-05 17:29:57 +08:00
add bench_uint16
Signed-off-by: Shikhar <shikharish05@gmail.com>
This commit is contained in:
parent
42ae960d95
commit
36d3441dc0
@ -11,7 +11,9 @@ FetchContent_MakeAvailable(counters)
|
||||
add_executable(realbenchmark benchmark.cpp)
|
||||
target_link_libraries(realbenchmark PRIVATE counters::counters)
|
||||
add_executable(bench_ip bench_ip.cpp)
|
||||
add_executable(bench_uint16 bench_uint16.cpp)
|
||||
target_link_libraries(bench_ip PRIVATE counters::counters)
|
||||
target_link_libraries(bench_uint16 PRIVATE counters::counters)
|
||||
|
||||
set_property(
|
||||
TARGET realbenchmark
|
||||
@ -19,8 +21,12 @@ set_property(
|
||||
set_property(
|
||||
TARGET bench_ip
|
||||
PROPERTY CXX_STANDARD 17)
|
||||
set_property(
|
||||
TARGET bench_uint16
|
||||
PROPERTY CXX_STANDARD 17)
|
||||
target_link_libraries(realbenchmark PUBLIC fast_float)
|
||||
target_link_libraries(bench_ip PUBLIC fast_float)
|
||||
target_link_libraries(bench_uint16 PUBLIC fast_float)
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
|
||||
139
benchmarks/bench_uint16.cpp
Normal file
139
benchmarks/bench_uint16.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
#include "counters/bench.h"
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <random>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
void pretty_print(size_t volume, size_t bytes, std::string name,
|
||||
counters::event_aggregate agg) {
|
||||
if (agg.inner_count > 1) {
|
||||
printf("# (inner count: %d)\n", agg.inner_count);
|
||||
}
|
||||
printf("%-40s : ", name.c_str());
|
||||
printf(" %5.2f GB/s ", bytes / agg.fastest_elapsed_ns());
|
||||
printf(" %5.1f Mip/s ", volume * 1000.0 / agg.fastest_elapsed_ns());
|
||||
printf(" %5.2f ns/ip ", agg.fastest_elapsed_ns() / volume);
|
||||
if (counters::event_collector().has_events()) {
|
||||
printf(" %5.2f GHz ", agg.fastest_cycles() / agg.fastest_elapsed_ns());
|
||||
printf(" %5.2f c/ip ", agg.fastest_cycles() / volume);
|
||||
printf(" %5.2f i/ip ", agg.fastest_instructions() / volume);
|
||||
printf(" %5.2f c/b ", agg.fastest_cycles() / bytes);
|
||||
printf(" %5.2f i/b ", agg.fastest_instructions() / bytes);
|
||||
printf(" %5.2f i/c ", agg.fastest_instructions() / agg.fastest_cycles());
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
enum class parse_method { standard, fast_float };
|
||||
|
||||
void validate(const std::string &buffer, const std::vector<uint16_t> &expected,
|
||||
char delimiter) {
|
||||
const char *p = buffer.data();
|
||||
const char *pend = p + buffer.size();
|
||||
|
||||
for (size_t i = 0; i < expected.size(); i++) {
|
||||
uint16_t val;
|
||||
auto r = fast_float::from_chars(p, pend, val);
|
||||
if (r.ec != std::errc() || val != expected[i]) {
|
||||
printf("Validation failed at index %zu: expected %u, got %u\n", i,
|
||||
expected[i], val);
|
||||
std::abort();
|
||||
}
|
||||
p = r.ptr;
|
||||
if (i + 1 < expected.size()) {
|
||||
if (p >= pend || *p != delimiter) {
|
||||
printf("Validation failed at index %zu: delimiter mismatch\n", i);
|
||||
std::abort();
|
||||
}
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
if (p != pend) {
|
||||
printf("Validation failed: trailing bytes remain\n");
|
||||
std::abort();
|
||||
}
|
||||
printf("Validation passed!\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
constexpr size_t N = 500000;
|
||||
constexpr char delimiter = ',';
|
||||
std::mt19937 rng(1234);
|
||||
std::uniform_int_distribution<int> dist(0, 65535);
|
||||
|
||||
std::vector<uint16_t> expected;
|
||||
expected.reserve(N);
|
||||
|
||||
std::string buffer;
|
||||
buffer.reserve(N * 6); // up to 5 digits + delimiter
|
||||
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
uint16_t val = (uint16_t)dist(rng);
|
||||
expected.push_back(val);
|
||||
std::string s = std::to_string(val);
|
||||
buffer.append(s);
|
||||
if (i + 1 < N) {
|
||||
buffer.push_back(delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
size_t total_bytes = buffer.size();
|
||||
|
||||
validate(buffer, expected, delimiter);
|
||||
|
||||
volatile uint64_t sink = 0;
|
||||
|
||||
pretty_print(N, total_bytes, "parse_uint16_std_fromchars",
|
||||
counters::bench([&]() {
|
||||
uint64_t sum = 0;
|
||||
const char *p = buffer.data();
|
||||
const char *pend = p + buffer.size();
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
uint16_t value = 0;
|
||||
auto r = std::from_chars(p, pend, value);
|
||||
if (r.ec != std::errc())
|
||||
std::abort();
|
||||
sum += value;
|
||||
p = r.ptr;
|
||||
if (i + 1 < N) {
|
||||
if (p >= pend || *p != delimiter)
|
||||
std::abort();
|
||||
++p;
|
||||
}
|
||||
}
|
||||
if (p != pend)
|
||||
std::abort();
|
||||
sink += sum;
|
||||
}));
|
||||
|
||||
pretty_print(N, total_bytes, "parse_uint16_fastfloat", counters::bench([&]() {
|
||||
uint64_t sum = 0;
|
||||
const char *p = buffer.data();
|
||||
const char *pend = p + buffer.size();
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
uint16_t value = 0;
|
||||
auto r = fast_float::from_chars(p, pend, value);
|
||||
if (r.ec != std::errc())
|
||||
std::abort();
|
||||
sum += value;
|
||||
p = r.ptr;
|
||||
if (i + 1 < N) {
|
||||
if (p >= pend || *p != delimiter)
|
||||
std::abort();
|
||||
++p;
|
||||
}
|
||||
}
|
||||
if (p != pend)
|
||||
std::abort();
|
||||
sink += sum;
|
||||
}));
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user