Created
April 21, 2012 18:45
-
-
Save laanwj/2439041 to your computer and use it in GitHub Desktop.
Bitcoin HexStr benchmarks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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