Autobahn|Cpp usage of boost::any and typeid

#1

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.

0 Likes

#2

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

···

Am 22.11.2014 16:55, schrieb David Chappelle:

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.

0 Likes

#3

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.

0 Likes

#4

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

···

Am 27.11.2014 23:41, schrieb emile.co...@gmail.com:

--
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.

0 Likes

#5

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.

···

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.

0 Likes

#6

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)

Am 29.11.2014 01:39 schrieb emile.co...@gmail.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.

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.

For more options, visit https://groups.google.com/d/optout.

0 Likes

#7

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::vectorboost::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?

···

On Saturday, November 29, 2014 2:49:01 AM UTC-4, Tobias Oberstein wrote:

0 Likes

#8

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).

···

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

0 Likes

#9

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).

···

On Saturday, November 29, 2014 11:09:42 AM UTC-4, emile...@gmail.com wrote:

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).

0 Likes

#10

    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.

0 Likes

#11

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

···

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).

0 Likes

#12

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

arg.isstd::string()

arg.asstd::string()

over

arg.type() == typeid(std::string)

boost::any_cast(arg)

The fault is boost::any’s and not yours. :slight_smile:

···

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.

0 Likes

#13

    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. :slight_smile:

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

···

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:

--
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>.
For more options, visit https://groups.google.com/d/optout.

0 Likes