Opened 14 years ago

Closed 14 years ago

Last modified 14 years ago

#2563 closed Feature Requests (invalid)

[boost][serialization] void_upcast is very slow

Reported by: jacobholm@… Owned by: Robert Ramey
Milestone: Boost 1.38.0 Component: serialization
Version: Boost 1.37.0 Severity: Optimization
Keywords: Cc:

Description

My preference would be to detect mulitple inheritance at compile time if that's possible.

Make a TRAK ticket for this item.

Robert Ramey

Jacob wrote: The original "inline void_upcast" method checks if the pointer to the object is of the right type, by traversing its parents. This is necessary when using multiple inheritance, since in such a case the adress of the pointer to the object can vary depending on which base class it is cast to.

While profiling one of my projects I noticed that most of the time was spent in the void_upcast method. I modified the method to return the pointer directly(see below), resulting in a high performance increase. This "solution" is possible if you avoid multiple inheritance all together, which I did. In my particular project I experienced a 75% speed increase implementing this, going from about 10 seconds to 2.5 seconds.

Would it be possible to implement some functionality to turn on and off the upcasting for given classes, kind of like the tracking of objects is currently administrated?

Modified "inline void_upcast":

/inline void *
void_upcast(
  extended_type_info const & derived,
  extended_type_info const & base,
  void * const t
){
   return const_cast<void*>(t);
 }/

Yours sincerely,

Jacob Holm

Attachments (1)

Main.cpp (2.4 KB ) - added by jacobholm@… 14 years ago.
static_cast test

Download all attachments as: .zip

Change History (5)

comment:1 by Robert Ramey, 14 years ago

Status: newassigned

I am interested in making the library faster.

But, I don't see your solution working execept in special cases. void_upcast also "shifts" the pointer much like

static_cast<A *>(b)

would. Your solution would work only when the derived class has not member variables

Robert Ramey

by jacobholm@…, 14 years ago

Attachment: Main.cpp added

static_cast test

comment:2 by jacobholm@…, 14 years ago

The project I am using contains derived classes with member variables. If possible, I think that the best way would be to modify void_upcast to use static_cast<T> with templates. That way one would be able to use multiple inheritance as well. Another solution could be to have an option to disable upcast alltogether, letting the user keep track of inheritance between classes. If used correctly this last solution will work with multiple inheritance as well.

I have attached an example cpp file to the ticket which uses static_cast on derived objects, together with multiple inheritance.

Yours sincerely,

Jacob Holm

comment:3 by Robert Ramey, 14 years ago

Resolution: invalid
Status: assignedclosed

I've looked at the code and your test. I've concluded the following:

a) I won't dispute that void_upcast is slower than a static cast. It may be possible to make it faster. b) I double checked the serialization code to verify that void_upcast was only being invoked when it was absolutely necessary. I'm satisfied that it is. c) So I've concluded that your proposed change will cause the serialization library to fail except in some cases. d) I took a look at your test. It's not obvious to me what it is actually meant to show and how it would relate to the replacement of void_upcast with a static cast.

Robert Ramey

comment:4 by jacobholm@…, 14 years ago

/inline void *
void_upcast(
 extended_type_info const & derived,
 extended_type_info const & base,
 void * const t
){
  return const_cast<void*>(t);
}/

The code above was the first to be suggested. This code will not work with multiple inheritance. Then there would be need for a method that detects if there is multiple inheritance or not. But if we were to modify it to use templates and static_cast it would work with multiple inheritance as well:

template <typename A>
class cast
{
public:

 template<typename B>
 static A* void_upcast(
   B* const t
 )
 {
   return static_cast<A*>(const_cast<B*>(t));
 }
};

Example using the above code:

const B *t;

cast<A*>::void_upcast(t);

This solution is based on that we know the class type so that we can call the template class.

I also have some comments your conclusions:

c) Why will the serialization fail with static_cast? Perhaps you could provide a code example?

d) It is meant to show that static_cast may change the pointer when casting with multiple inheritance, and never change the pointer when using single inheritance.

Yours sincerely,

Jacob Holm

Note: See TracTickets for help on using tickets.