1
0
Fork 0
forked from lthn/blockchain

minor refactoring around crypto::pod_to_hex (added generalized buff_to_hex + performance test)

This commit is contained in:
sowle 2024-10-16 00:01:43 +02:00
parent 9186119620
commit 3c23d42ae4
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
2 changed files with 82 additions and 19 deletions

View file

@ -51,38 +51,42 @@ namespace crypto
}
template<class pod_t>
std::string pod_to_hex_reversed(const pod_t &h)
inline std::string buff_to_hex(const void* pdata, size_t len, bool reversed = false)
{
constexpr char hexmap[] = "0123456789abcdef";
const unsigned char* data = reinterpret_cast<const unsigned char*>(&h);
size_t len = sizeof h;
const unsigned char* data = reinterpret_cast<const unsigned char*>(pdata);
std::string s(len * 2, ' ');
for (size_t i = 0; i < len; ++i)
if (!reversed)
{
s[2 * i] = hexmap[data[len - 1 - i] >> 4];
s[2 * i + 1] = hexmap[data[len - 1 - i] & 0x0F];
for (size_t i = 0; i < len; ++i)
{
s[2 * i] = hexmap[data[i] >> 4];
s[2 * i + 1] = hexmap[data[i] & 0x0F];
}
}
else
{
for (size_t i = 0; i < len; ++i)
{
s[2 * i] = hexmap[data[len - 1 - i] >> 4];
s[2 * i + 1] = hexmap[data[len - 1 - i] & 0x0F];
}
}
return s;
}
template<class pod_t>
std::string pod_to_hex_reversed(const pod_t &h)
{
return buff_to_hex(&h, sizeof h, true);
}
template<class pod_t>
std::string pod_to_hex(const pod_t &h)
{
constexpr char hexmap[] = "0123456789abcdef";
const unsigned char* data = reinterpret_cast<const unsigned char*>(&h);
size_t len = sizeof h;
std::string s(len * 2, ' ');
for (size_t i = 0; i < len; ++i)
{
s[2 * i] = hexmap[data[i] >> 4];
s[2 * i + 1] = hexmap[data[i] & 0x0F];
}
return s;
return buff_to_hex(&h, sizeof h);
}
template<class pod_t>

View file

@ -5,6 +5,7 @@
//
#pragma once
#include <numeric>
#include "crypto/crypto-sugar.h" // just for intellysense
uint64_t get_bits_v1(const scalar_t& s, uint8_t bit_index_first, uint8_t bits_count)
{
@ -1338,3 +1339,61 @@ TEST(perf, point_eq_vs_iszero)
return true;
}
TEST(perf, buff_to_hex)
{
std::vector<std::string> in_buffs;
std::vector<std::string> out_hexs;
std::vector<uint64_t> timings1, timings2;
size_t N = 10000;
in_buffs.reserve(N);
out_hexs.reserve(N);
for(size_t i = 0; i < N; ++i)
{
size_t len = (crypto::rand<uint32_t>() % 128) + 1; // [1; 128]
std::string& buff = in_buffs.emplace_back();
buff.resize(len);
generate_random_bytes(len, buff.data());
}
size_t rounds = 100, warmup_rounds = 20;
for(size_t i = 0; i < warmup_rounds + rounds; ++i)
{
out_hexs.clear();
TIME_MEASURE_START(t1);
for(size_t j = 0; j < N; ++j)
out_hexs.push_back(epee::string_tools::buff_to_hex_nodelimer(in_buffs[j]));
TIME_MEASURE_FINISH(t1);
uint64_t h1 = 0;
for(size_t j = 0; j < N; ++j)
h1 ^= hash_64(out_hexs[j].data(), out_hexs[j].size());
out_hexs.clear();
TIME_MEASURE_START(t2);
for(size_t j = 0; j < N; ++j)
out_hexs.push_back(crypto::buff_to_hex(in_buffs[j].data(), in_buffs[j].size()));
TIME_MEASURE_FINISH(t2);
uint64_t h2 = 0;
for(size_t j = 0; j < N; ++j)
h2 ^= hash_64(out_hexs[j].data(), out_hexs[j].size());
ASSERT_EQ(h1, h2);
if (i >= warmup_rounds)
{
timings1.push_back(t1);
timings2.push_back(t2);
}
}
std::cout << "After " << rounds << " rounds:" << ENDL <<
"epee::string_tools::buff_to_hex_nodelimer : " << epee::misc_utils::median(timings1) << " mcs" << ENDL <<
"crypto::buff_to_hex : " << epee::misc_utils::median(timings2) << " mcs" << ENDL;
return true;
}