saleyn / eixx

Erlang C++ Interface
Apache License 2.0
137 stars 26 forks source link

Allow header-only marshalling, no need for libeixx.so #7

Closed erlanger closed 9 years ago

erlanger commented 9 years ago

Header-only marshalling

This is a simple patch, all the tests pass without errors. I moved the link-time objects that were required for marshalling into the headers.

This will allow people to use the marshalling functionality without linking to libeixx.so, only using the eterm.hpp header with one of the alloc headers. e.g.

#include "eixx/alloc_std.hpp"
#include "eixx/eterm.hpp"
int main()
{  
   eixx::eterm t0 = eixx::eterm::format("{ ok, 30,\"hello, I am ok\",atom1,40.1,50}");
   auto t0ext = t0.encode(0);
}

compile with

g++ -std=c++11 -o e -I eixx/include -I /usr/lib/erlang/lib/erl_interface-3.7.18/include/ -L /usr/lib/erlang/lib/erl_interface-3.7.18/lib/ eixx.cpp  -lei

(notice no need for -leixx)

For some objects I simply made an inline static function to return the object (to prevent multiple definitions of the same object).

Unintended side-effect: Speed

It had the nice side effect of making it a little faster, from 6.28us total time to 5.86us. I presume it is because of the inlining of functions. With the patch:

./test_perf  #with the patch
                        500000 iterations
                       Integer | 0.010000 (speed: 0.020us)
                        Double | 0.010000 (speed: 0.020us)
                          Bool | 0.010000 (speed: 0.020us)
                        String | 0.446667 (speed: 0.893us)
                         Atom1 | 0.406667 (speed: 0.813us)
                         Atom2 | 0.423334 (speed: 0.847us)
                       Binary1 | 0.596666 (speed: 1.193us)
                       Binary2 | 0.026666 (speed: 0.053us)
                        Tuple1 | 1.103334 (speed: 2.207us)
                        Tuple2 | 0.070000 (speed: 0.140us)
                         List1 | 1.580000 (speed: 3.160us)
                         List2 | 1.156666 (speed: 2.313us)
                    Total time | 5.863333 (speed: 11.727us)

Without the patch:

 ./test_perf  #without the patch
                        500000 iterations
                       Integer | 0.010000 (speed: 0.020us)
                        Double | 0.010000 (speed: 0.020us)
                          Bool | 0.006667 (speed: 0.013us)
                        String | 0.506667 (speed: 1.013us)
                         Atom1 | 0.436667 (speed: 0.873us)
                         Atom2 | 0.433334 (speed: 0.867us)
                       Binary1 | 0.613333 (speed: 1.227us)
                       Binary2 | 0.030000 (speed: 0.060us)
                        Tuple1 | 1.230000 (speed: 2.460us)
                        Tuple2 | 0.086666 (speed: 0.173us)
                         List1 | 1.770000 (speed: 3.540us)
                         List2 | 1.130000 (speed: 2.260us)
                    Total time | 6.279999 (speed: 12.560us)

Hope you find it useful and also your users.

erlanger commented 9 years ago

We can make it even easier by not requiring bootsrap && configure for marshalling. I just tried it with my patch applied and the only error I get is that the compiler can't find eixx/config.h ; I placed an empty include/eixx/config.h and everything compiled and worked fine without bootstrap, configure && make. I haven't looked at the side-effects of the empty config.h (like missing the EIXX version number , etc) so I will leave it for later.

erlanger commented 9 years ago

oops, in the speed comparison I meant seconds not micro-seconds. Sorry....