Skip to content

Instantly share code, notes, and snippets.

@frsyuki
Created April 26, 2010 14:07
Show Gist options
  • Save frsyuki/379379 to your computer and use it in GitHub Desktop.
Save frsyuki/379379 to your computer and use it in GitHub Desktop.
#include <msgpack.hpp>
#include <iostream>
#include <sys/time.h>
#include <vector>
struct simple_timer {
void reset() { gettimeofday(&m_timeval, NULL); }
void show()
{
struct timeval endtime;
gettimeofday(&endtime, NULL);
double sec = (endtime.tv_sec - m_timeval.tv_sec)
+ (double)(endtime.tv_usec - m_timeval.tv_usec) / 1000 / 1000;
std::cout << sec << " sec" << std::endl;
}
private:
struct timeval m_timeval;
};
struct insufficient_buffer_error : public std::runtime_error {
insufficient_buffer_error() :
std::runtime_error("buffer is insufficient") { }
};
#define MORE(N) if(m_remain < N) { throw insufficient_buffer_error(); }
#define ADVANCE(N) m_pos += N; m_remain -= N;
class unpacker2 {
public:
inline uint64_t unpack_uint64()
{
uint64_t v;
MORE(1);
if(m_pos[0] <= 0x7f) {
// positivie fixnum
v = *(uint8_t*)m_pos;
ADVANCE(1);
} else if(m_pos[0] == 0xcc) {
// unsigned int 8
MORE(2);
v = *(uint8_t*)(m_pos+1);
ADVANCE(2);
} else if(m_pos[0] == 0xcd) {
// unsigned int 16
MORE(3);
v = _msgpack_be16( *(uint16_t*)(m_pos+1) );
ADVANCE(3);
} else if(m_pos[0] == 0xce) {
// unsigned int 32
MORE(5);
v = _msgpack_be32( *(uint32_t*)(m_pos+1) );
ADVANCE(5);
} else if(m_pos[0] == 0xcf) {
// unsigned int 64
MORE(9);
v = _msgpack_be64( *(uint64_t*)(m_pos+1) );
ADVANCE(9);
} else {
throw msgpack::type_error();
}
return v;
}
inline uint32_t unpack_array()
{
uint32_t len;
MORE(1);
if(0x0a <= m_pos[0] && m_pos[0] <= 0xbf) {
// fixarray
len = ((unsigned int)m_pos[0]) & 0x0f;
ADVANCE(1);
} else if(m_pos[0] == 0xdc) {
// array 16
MORE(3);
len = _msgpack_be16( *(uint16_t*)(m_pos+1) );
ADVANCE(3);
} else if(m_pos[0] == 0xdd) {
// array 32
MORE(5);
len = _msgpack_be32( *(uint32_t*)(m_pos+1) );
ADVANCE(5);
}
return len;
}
public:
unsigned char* m_buffer;
unsigned char* m_pos;
size_t m_remain;
};
int main(int argc, char* argv[])
{
simple_timer timer;
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> pk(sbuf);
const size_t loop = atoi(argv[1]);
pk.pack_array(loop);
for(size_t i=0; i < loop; ++i) {
msgpack::pack(sbuf, i);
}
// static unpacker
timer.reset();
{
unpacker2 pac;
pac.m_buffer = (unsigned char*)sbuf.data();
pac.m_pos = pac.m_buffer;
pac.m_remain = sbuf.size();
std::vector<uint64_t> result;
uint32_t len = pac.unpack_array();
result.reserve(len);
for(size_t i=0; i < len; ++i) {
uint64_t v = pac.unpack_uint64();
result.push_back(v);
}
}
timer.show();
// dynamic unpacker + type conversion
timer.reset();
{
msgpack::zone z;
msgpack::object obj;
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
std::vector<uint64_t> result;
obj.convert(&result);
}
timer.show();
}
// $ ./a.out 10000
// 0.000489 sec
// 0.000974 sec
// $ ./a.out 1000000
// 0.040277 sec
// 0.084064 sec
// Mac OS X Snow Leopard
// Intel Core 2 Duo 2.53 GHz
// DDR3 1067MHz 8GB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment