Skip to content

Instantly share code, notes, and snippets.

@laanwj
Created April 21, 2012 18:45
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 laanwj/2439041 to your computer and use it in GitHub Desktop.
Save laanwj/2439041 to your computer and use it in GitHub Desktop.
Bitcoin HexStr benchmarks
// g++ -O2 hexstr_benchmarks.cpp -o hexstr_benchmarks
#include <stdio.h>
#include <vector>
#include <string>
#include <stdarg.h>
#include <time.h>
#include <string.h>
using namespace std;
#define loop for (;;)
#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
#define ITERATIONS 1000000
static const unsigned char ParseHex_expected[65] = {
0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12,
0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
0x5f
};
template<typename T>
std::string HexStrNew(const T itbegin, const T itend, bool fSpaces=false)
{
std::vector<char> rv;
static char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
rv.reserve((itend-itbegin)*3);
for(T it = itbegin; it < itend; ++it)
{
unsigned char val = (unsigned char)(*it);
if(fSpaces && it != itbegin)
rv.push_back(' ');
rv.push_back(hexmap[val>>4]);
rv.push_back(hexmap[val&15]);
}
return std::string(rv.begin(), rv.end());
}
#define strprintf(format, ...) real_strprintf(format, 0, __VA_ARGS__)
string real_strprintf(const std::string &format, int dummy, ...)
{
char buffer[50000];
char* p = buffer;
int limit = sizeof(buffer);
int ret;
loop
{
va_list arg_ptr;
va_start(arg_ptr, dummy);
ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
va_end(arg_ptr);
if (ret >= 0 && ret < limit)
break;
if (p != buffer)
delete[] p;
limit *= 2;
p = new char[limit];
if (p == NULL)
throw std::bad_alloc();
}
string str(p, p+ret);
if (p != buffer)
delete[] p;
return str;
}
char* ToHex(const char *ptr, int len, char *outbuf)
{ // max length is 255
static char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
char *outptr = outbuf;
unsigned char *iptr = (unsigned char *) ptr;
while (len-- > 0)
{
*outptr++ = hexmap[*iptr>>4];
*outptr++ = hexmap[*iptr&15];
iptr++;
}
*outptr=0;
return outbuf;
}
template<typename T>
std::string HexStrOld(const T itbegin, const T itend, bool fSpaces=false)
{
if (itbegin == itend)
return "";
const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
std::string str;
str.reserve((pend-pbegin) * (fSpaces ? 3 : 2));
for (const unsigned char* p = pbegin; p != pend; p++)
str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
return str;
}
int main()
{
printf("Testing HexStrOld (%i iterations)\n", ITERATIONS);
int tsize = 0;
clock_t t_begin, t_end;
t_begin = clock();
for(int i=0; i<ITERATIONS; ++i)
{
std::string rv = HexStrOld(ParseHex_expected, ParseHex_expected+sizeof(ParseHex_expected));
tsize += rv.size();
}
t_end = clock();
printf("-> %.1f ms\n", (t_end-t_begin)*1e-3);
printf("Testing HexStrNew (%i iterations)\n", ITERATIONS);
tsize = 0;
t_begin = clock();
for(int i=0; i<ITERATIONS; ++i)
{
std::string rv = HexStrNew(ParseHex_expected, ParseHex_expected+sizeof(ParseHex_expected));
tsize += rv.size();
}
t_end = clock();
printf("-> %.1f ms\n", (t_end-t_begin)*1e-3);
printf("Testing ToHex (%i iterations)\n", ITERATIONS);
tsize = 0;
t_begin = clock();
char outbuf[1000];
for(int i=0; i<ITERATIONS; ++i)
{
ToHex((const char*)ParseHex_expected, sizeof(ParseHex_expected), outbuf);
tsize += strlen(outbuf);
}
t_end = clock();
printf("-> %.1f ms\n", (t_end-t_begin)*1e-3);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment