Ask Your Question
2

difference between receiving a reference or a Ptr in a callback

asked 2013-09-19 08:45:28 -0500

brice rebsamen gravatar image

updated 2014-03-04 06:30:04 -0500

assume 2 callbacks:

void cb1(const MsgType &);
void cb2(const MsgType::ConstPtr &);

In the case of cb2, each time a message is received a new object is created, i.e. memory allocation occurs. Well unless it's a nodelet, in which case the memory was allocated by the sender... but I'm not talking about that...

What about cb1? Is it the same object each time, i.e. memory does not need to be allocated if the message is the same size? That could save some time when dealing with large messages...

EDIT: Since nobody understood my question, I'll try to reformulate. Actually I'd love to look at the actual code that does the deserialization and calls the callback function. Can somebody points it to me?

Here is 2 possible implementations of the message queue. This is pseudo code... but which concept is closer to the actual implementation?

// implementation that does not allocate the memory for each new message
class MessageQueue {
    queue<MsgType::SerializedType> serialized_msgs_;
    MsgType deserialized_msg_; //this object is allocated only once and reused

    void process() {
        deserialized_msg_.deserialize(serialized_msgs_.front());
        serialized_msgs_.pop();
        notify_callback( deserialized_msg_ ); //pass by const reference
    }
};

// another implementation that allocates new memory each time
class MessageQueue {
    queue<MsgType::SerializedType> serialized_msgs_;

    void process() {
        // allocate a new object each time
        MsgTypePtr deserialized_msg(new MsgType);
        deserialized_msg->deserialize(serialized_msgs_.front());
        serialized_msgs_.pop();
        notify_callback(deserialized_msg);
    }
};

In the first implementation, if we are dealing with a message that is always the same size, then no allocation is required at all which makes the code super efficient.

edit retag flag offensive close merge delete

Comments

As far as I understood, both of them don't require coping. In other words, the first callback with reference creates just an alias(no memory allocation involved) and the other one creates a const pointer(no memory allocation involved as well).

alfa_80 gravatar image alfa_80  ( 2013-09-19 20:15:04 -0500 )edit

3 Answers

Sort by ยป oldest newest most voted
3

answered 2013-09-19 21:41:16 -0500

Adolfo Rodriguez T gravatar image

MsgType::ConstPtr is a typedef to a boost::shared_ptr<const MsgType>. What you win with a MsgType::ConstPtr is that you can store it and control its lifecycle, eg. for use outside the callback without incurring an extra copy.

With a plain const MsgType& the message data will go out of scope with the callback, and you'll have to make a copy to access the data from outside the callback.

edit flag offensive delete link more
1

answered 2020-05-02 10:49:56 -0500

YuehChuan gravatar image

I made a test, the result seems no performance difference. I wonder whether I missed something.

test https://www.youtube.com/watch?v=mdaTj... code https://github.com/YuehChuan/ros-call...

edit flag offensive delete link more
1

answered 2013-09-19 21:44:51 -0500

tfoote gravatar image

A reference does not make a copy, it is only guaranteed to be in scope for the duration of the callback.

The ConstPtr is a Boost Shared Pointer which will reference count the underlying data, and copies of the pointer can be persisted and will keep the data in scope for longer.

I suggest getting more information from pure C++ forums such as Stack Overflow. There are lots of valuable reading threads This is a little off topic for ROS Answers.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2013-09-19 08:45:28 -0500

Seen: 3,234 times

Last updated: Mar 04 '14