diff --git a/cpp/Makefile b/cpp/Makefile index 7cc66b2c..4a3677e9 100644 --- a/cpp/Makefile +++ b/cpp/Makefile @@ -1,11 +1,11 @@ -CXXFLAGS = -I.. -I. -Wall -g -#CXXFLAGS = -I.. -I. -Wall -g -O4 -LDFLAGS = -L. +#CXXFLAGS = -I.. -I. -Wall -g +CXXFLAGS = -I.. -I. -Wall -g -O4 +LDFLAGS = -L. $(CXXFLAGS) NEED_PREPROCESS = zone.hpp -all: test +all: test bench %.hpp: %.hpp.erb erb $< > $@ @@ -13,10 +13,13 @@ all: test test: $(NEED_PREPROCESS) unpack.o unpack_inline.o object.o zone.o test.o object.hpp unpack.hpp pack.hpp $(CXX) $(LDFLAGS) unpack.o unpack_inline.o zone.o object.o test.o -o $@ +bench: $(NEED_PREPROCESS) unpack.o unpack_inline.o object.o zone.o bench.o object.hpp unpack.hpp pack.hpp + $(CXX) $(LDFLAGS) unpack.o unpack_inline.o zone.o object.o bench.o -o $@ + .PHONY: clean clean: $(RM) unpack.o unpack_inline.o object.o zone.o - $(RM) test.o - $(RM) test + $(RM) test.o test + $(RM) bench.o bench $(RM) $(NEED_PREPROCESS) diff --git a/cpp/bench.cpp b/cpp/bench.cpp new file mode 100644 index 00000000..1a9f6f92 --- /dev/null +++ b/cpp/bench.cpp @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include +#include + +static const unsigned int TASK_INT_NUM = 1<<24; +static const unsigned int TASK_STR_LEN = 1<<15; +//static const unsigned int TASK_INT_NUM = 1<<23; +//static const unsigned int TASK_STR_LEN = 1<<14; +static const void* TASK_STR_PTR; + + +class simple_timer { +public: + void reset() { gettimeofday(&m_timeval, NULL); } + void show_stat(size_t bufsz) + { + 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; + std::cout << (double(bufsz)/1024/1024) << " MB" << std::endl; + std::cout << (bufsz/sec/1024/1024*8) << " Mbps" << std::endl; + } +private: + timeval m_timeval; +}; + + +class simple_buffer { +public: + static const size_t DEFAULT_INITIAL_SIZE = 32*1024;//512*1024*1024*2; + + simple_buffer(size_t initial_size = DEFAULT_INITIAL_SIZE) : + m_storage((char*)malloc(initial_size)), + m_allocated(initial_size), + m_used(0) + { + if(!m_storage) { throw std::bad_alloc(); } + } + + ~simple_buffer() + { + free(m_storage); + } + +public: + inline simple_buffer& append(const char* buf, size_t len) + { + if(m_allocated - m_used < len) { + expand_buffer(len); + } + memcpy(m_storage + m_used, buf, len); + m_used += len; + return *this; + } + + void clear() + { + m_used = 0; + } + +private: + void expand_buffer(size_t req) + { + size_t nsize = m_allocated * 2; + size_t at_least = m_used + req; + while(nsize < at_least) { nsize *= 2; } + char* tmp = (char*)realloc(m_storage, nsize); + if(!tmp) { throw std::bad_alloc(); } + m_storage = tmp; + m_allocated = nsize; + } + +public: + size_t size() const { return m_used; } + const char* data() const { return m_storage; } + +private: + char* m_storage; + size_t m_allocated; + size_t m_used; +}; + + +void bench_msgpack_int() +{ + simple_buffer buf; + simple_timer timer; + + std::cout << "----" << std::endl; + std::cout << "pack integer" << std::endl; + + timer.reset(); + { + msgpack::packer pk(buf); + pk.pack_array(TASK_INT_NUM); + for(unsigned int i=0; i < TASK_INT_NUM; ++i) { + pk.pack_unsigned_int(i); + } + } + timer.show_stat(buf.size()); + + std::cout << "----" << std::endl; + std::cout << "unpack integer" << std::endl; + + msgpack::zone z; + msgpack::object obj; + + timer.reset(); + { + obj = msgpack::unpack(buf.data(), buf.size(), z); + } + timer.show_stat(buf.size()); + + std::cout << "----" << std::endl; + std::cout << "dynamic pack integer" << std::endl; + + buf.clear(); + + timer.reset(); + msgpack::pack(buf, obj); + timer.show_stat(buf.size()); +} + +void bench_msgpack_str() +{ + simple_buffer buf; + simple_timer timer; + + std::cout << "----" << std::endl; + std::cout << "pack string" << std::endl; + + timer.reset(); + { + msgpack::packer pk(buf); + pk.pack_array(TASK_STR_LEN); + for(unsigned int i=0; i < TASK_STR_LEN; ++i) { + pk.pack_raw(TASK_STR_PTR, i); + } + } + timer.show_stat(buf.size()); + + std::cout << "----" << std::endl; + std::cout << "unpack string" << std::endl; + + msgpack::zone z; + msgpack::object obj; + + timer.reset(); + { + obj = msgpack::unpack(buf.data(), buf.size(), z); + } + timer.show_stat(buf.size()); + + std::cout << "----" << std::endl; + std::cout << "dynamic pack string" << std::endl; + + buf.clear(); + + timer.reset(); + msgpack::pack(buf, obj); + timer.show_stat(buf.size()); +} + +int main(void) +{ + void* str = malloc(TASK_STR_LEN); + memset(str, 'a', TASK_STR_LEN); + TASK_STR_PTR = str; + + bench_msgpack_int(); + bench_msgpack_str(); + + return 0; +} + diff --git a/cpp/unpack.cpp b/cpp/unpack.cpp index d4845938..807ded9f 100644 --- a/cpp/unpack.cpp +++ b/cpp/unpack.cpp @@ -85,8 +85,8 @@ void unpacker::expand_buffer(size_t len) void* tmp = malloc(next_size); if(!tmp) { throw std::bad_alloc(); } memcpy(tmp, m_buffer, m_used); - free(m_buffer); + m_buffer = tmp; m_free = next_size - m_used;