Created
April 26, 2010 14:07
-
-
Save frsyuki/379379 to your computer and use it in GitHub Desktop.
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
#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