Autobahn|Cpp usage of boost::any and typeid

54 views
Skip to first unread message

David Chappelle

unread,
Nov 22, 2014, 10:55:40 AM11/22/14
to autob...@googlegroups.com
Curious if there is any negative impact due to the use of boost::any and typeid. For example:

Is boost::any a potential performance problem?

Is relying on RTTI for typeid acceptable? My experience is that this is typically frowned upon.

Tobias Oberstein

unread,
Nov 22, 2014, 3:32:13 PM11/22/14
to autob...@googlegroups.com
WAMP is dynamically typed, hence we need a flexible value system.
Relying on something (boost::any) that comes with a widely used library
(Boost) seems least intrusive and sane.

To identify the type of the actual value contained in a boost::any is
done by calling type(), and this returns std::type_info.

The only thing you can do is basically comparing of equality/inequality
to another type_info (hence the value.type() == typeid(X) constructs).

We could probably use hash_value() and cache those on the session class
before, but I'm not sure it's worth.

Performance is relative. I suspect that compared to
serialization/deserialization and networking (be it via unix domain
sockets or even more so TCP) will dwarf anything related to above.

/Tobias



emile.co...@gmail.com

unread,
Nov 27, 2014, 5:41:08 PM11/27/14
to autob...@googlegroups.com
I've been looking at this recently, and I think that perhaps a recursive boost::variant might have worked better here than boost::any. boost::variant supports the Visitor pattern, which would avoid having to do all this RTTI stuff.

Tobias Oberstein

unread,
Nov 28, 2014, 6:15:19 PM11/28/14
to autob...@googlegroups.com
Am 27.11.2014 23:41, schrieb emile.co...@gmail.com:
> I've been looking at this recently, and I think that perhaps a recursive
> boost::variant /might/ have worked better here than boost::any.

I was indeed chosing between three options for the user API:

- boost::any
- boost::variant
- something other (non-Boost)

and chose the first after ruling out 3) (no additional dep in the user
API).

> boost::variant supports the Visitor pattern, which would avoid having to
> do all this RTTI stuff.

What is the actual problem in RTTI? Anyway, it's an implementation detail.

/Tobias

>
> --
> You received this message because you are subscribed to the Google
> Groups "Autobahn" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to autobahnws+...@googlegroups.com
> <mailto:autobahnws+...@googlegroups.com>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/autobahnws/74bdf654-024d-4961-9b65-7089ef04ee55%40googlegroups.com
> <https://groups.google.com/d/msgid/autobahnws/74bdf654-024d-4961-9b65-7089ef04ee55%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

emile.co...@gmail.com

unread,
Nov 28, 2014, 7:39:43 PM11/28/14
to autob...@googlegroups.com
On Friday, November 28, 2014 7:15:19 PM UTC-4, Tobias Oberstein wrote:
 
What is the actual problem in RTTI? Anyway, it's an implementation detail.

IMHO, the main problem with RTTI is maintenance. If you add a class to your hierarchy, you have to remember to update all your switch statements (or if-else chains). But in this case, since JSON will not change, maintenance might not be so much of an issue.

Another problem with boost::any is that it has to dynamically allocate storage for the stored object. For a complex dynamic data types and for arrays, this results in lots of dynamic memory allocations. On the other hand, boost::variant uses stack-based storage. The tradeoffs of Boost.Variant vs Boost.Any are listed here.

The downside of boost::variant is that it's not trivial to implement a recursive one that handles JSON. It even stumped Dave Abrahams. Apparently, the problem lies in standard library containers not being required to support incomplete types.

To satisfy my own curiosity, I'm currently researching exactly how one can use boost::variant to model JSON objects.

Tobias Oberstein

unread,
Nov 29, 2014, 1:49:01 AM11/29/14
to autobahnws

As you said: JSON or MsgPack base types are a fixed set, so there is no issue of forgetting stuff.

Rgd dynamic memory allocation: how do you process incoming JSON without the former? A JSON string isn't even length prefixed, so there is no way of getting rid of malloc down somewhere ..

One perspective I was contemplating about was adding a 3rd option for WAMP serialization that does in fact do away with it altogether .. the Cap'n'Proto approach

Sent from Mobile (Google Nexus 5)

--
You received this message because you are subscribed to the Google Groups "Autobahn" group.
To unsubscribe from this group and stop receiving emails from it, send an email to autobahnws+...@googlegroups.com.
To post to this group, send email to autob...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/autobahnws/121bbe79-4500-4bd6-8e87-2157d767da01%40googlegroups.com.

emile.co...@gmail.com

unread,
Nov 29, 2014, 9:47:31 AM11/29/14
to autob...@googlegroups.com
On Saturday, November 29, 2014 2:49:01 AM UTC-4, Tobias Oberstein wrote:

Rgd dynamic memory allocation: how do you process incoming JSON without the former? A JSON string isn't even length prefixed, so there is no way of getting rid of malloc down somewhere ..

I don't know much about the internals of boost::variant, but I suspect that memory allocations are avoided for numeric types and small strings (due to the small string optimization).

In the case of vectors of boost::variant, memory would be allocated in contiguous chunks. On the other hand, a std::vector<boost::any> would end up making a memory allocation for each individual element.
 

One perspective I was contemplating about was adding a 3rd option for WAMP serialization that does in fact do away with it altogether .. the Cap'n'Proto approach

Did you mean using the Cap'n'Proto approach of serialization based on an IDL (for serialization into MsgPack or JSON), or using the Cap'n'Proto wire protocol as a third serialization format alongside MsgPack and JSON?

emile.co...@gmail.com

unread,
Nov 29, 2014, 10:09:42 AM11/29/14
to autob...@googlegroups.com
On Saturday, November 29, 2014 2:49:01 AM UTC-4, Tobias Oberstein wrote:

One perspective I was contemplating about was adding a 3rd option for WAMP serialization that does in fact do away with it altogether .. the Cap'n'Proto approach

As an alternative to boost::any and boost::variant, I had thought about writing a variant-like document class similar to rapidjson::Document. This document class could be a wrapper around boost::any or boost::variant, but would make it much easier to check the dynamic type and to convert to a static type (without having to use verbose and unwieldy cast expressions).

emile.co...@gmail.com

unread,
Nov 29, 2014, 10:24:10 AM11/29/14
to autob...@googlegroups.com
Or, perhaps, this proposed document class could made to use C++11's unrestricted unions.

I wonder if there's a better name than "document". How about "object"? Or perhaps "variant" (within the autobahn namespace, of course).

Tobias Oberstein

unread,
Nov 30, 2014, 10:26:58 AM11/30/14
to autob...@googlegroups.com
> One perspective I was contemplating about was adding a 3rd option
> for WAMP serialization that does in fact do away with it altogether
> .. the Cap'n'Proto approach
>
> Did you mean using the Cap'n'Proto approach of serialization based on an
> IDL (for serialization into MsgPack or JSON), or using the Cap'n'Proto
> wire protocol as a third serialization format alongside MsgPack and JSON?

Neither nor.

I meant adding Cap'n'Proto's "serialization" format as a 3rd
serialization format to WAMP.

Cap'n'Proto serialization works in place without any actual
serialization/deserialization at all.

Tobias Oberstein

unread,
Nov 30, 2014, 10:29:22 AM11/30/14
to autob...@googlegroups.com
Am 29.11.2014 16:09, schrieb emile.co...@gmail.com:
> On Saturday, November 29, 2014 2:49:01 AM UTC-4, Tobias Oberstein wrote:
>
> One perspective I was contemplating about was adding a 3rd option
> for WAMP serialization that does in fact do away with it altogether
> .. the Cap'n'Proto approach
>
> As an alternative to *boost::any* and *boost::variant*, I had thought
> about writing a variant-like *document* class similar to
> *rapidjson::Document*. This *document* class could be a wrapper around
> *boost::any* or *boost::variant*, but would make it much easier to check
> the dynamic type and to convert to a static type (without having to use
> verbose and unwieldy cast expressions).

Where is the current code "verbose and unwieldy"? The code is next to
trivial.

I wouldn't support changing the API for no actual gain. Adding a wrapper
around boost::any doesn't provide advantages. At least not that I see ..

Cheers,
/Tobias

emile.co...@gmail.com

unread,
Nov 30, 2014, 12:20:08 PM11/30/14
to autob...@googlegroups.com
On Sunday, November 30, 2014 11:29:22 AM UTC-4, Tobias Oberstein wrote:
Where is the current code "verbose and unwieldy"? The code is next to
trivial.

I meant unwieldy for the user of the library. I much prefer:

arg.is<std::string>()
arg.as<std::string>()

over

arg.type() == typeid(std::string)
boost::any_cast<int>(arg)

The fault is boost::any's and not yours. :-)

Tobias Oberstein

unread,
Nov 30, 2014, 1:49:41 PM11/30/14
to autob...@googlegroups.com
Am 30.11.2014 18:20, schrieb emile.co...@gmail.com:
> On Sunday, November 30, 2014 11:29:22 AM UTC-4, Tobias Oberstein wrote:
>
> Where is the current code "verbose and unwieldy"? The code is next to
> trivial.
>
>
> I meant unwieldy for the user of the library. I much prefer:
>
> arg.is<std::string>()
> arg.as<std::string>()
>
> over
>
> arg.type() == typeid(std::string)
> boost::any_cast<int>(arg)

Ahhh, I see. I thought you were refering to the code within the
implementation, not user code.

Why not just cast without testing and cope with the exception that might
be triggered?

>
> The fault is boost::any's and not yours. :-)

Well, I'm a guilty for chosing boost::any as core type for user API of
AutobahnCpp;)

And I do care about user API more than anything else. We can fix
anything internal now or later. But we need to get the API right.

I think the API is fine. You seem to have something different in mind.
I'd be very interested in your alternative API - even only a design
sketch (but one that covers all 4 interactions) ..

Cheers,
/Tobias

>
> --
> You received this message because you are subscribed to the Google
> Groups "Autobahn" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to autobahnws+...@googlegroups.com
> <mailto:autobahnws+...@googlegroups.com>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/autobahnws/c0512893-02a7-4990-9555-c79be578c1da%40googlegroups.com
> <https://groups.google.com/d/msgid/autobahnws/c0512893-02a7-4990-9555-c79be578c1da%40googlegroups.com?utm_medium=email&utm_source=footer>.
Reply all
Reply to author
Forward
0 new messages