rahman
rahman

Reputation: 4948

Can converting structure elements to const-reference save some overhead?

Scenario,

I have a trace file having thousands of 'Entries'(I call them 'tick'). Each 'Entry' contains several lines of information. There are two types of information(location data and multicast data) so each line is either about 'location' or 'multicast'.

Goal: My goal is to store them into my data structure efficiently:

Implementation:

for storing information of each entry, I have :

//////////////////
struct multicast_data{
//... integers, vectors of integers, string etc.
}
std::list<multicast_data> multicasts;
///////////////////////
struct AgentLocation{
 //... integers, operator overload etc.
};
std::set<AgentLocation> agentsLocation;
////////////////////////

Next, I want to store the entries in a queue, So I first bundle them in another structure like this:

struct tickDataBundle{
        const std::list<multicast_data> & multicasts;
        const std::set<AgentLocation> & agentsLocation;
        tickDataBundle(const std::list<multicast_data> &multicasts,
                const std::set<AgentLocation> &agentsLocation):
                    multicasts(multicasts),
                    agentsLocation(agentsLocation){}
    };

then I put them into a queue:

MessageQueue<tickDataBundle> m_processed_data;

Questions:

  1. My confusion is, the containers(list and set) in tickDataBundle are created and populated in the scope of some method, and naturally these containers are destroyed when the scope ends(no heap). So even returning the reference to these containers will create dangling reference. So I figured if,before the scope ends, I add the const-reference of these containers to tickDataBundle object, then push this object to the MessageQueue , I would have benefitted from the C++'s optimization to save the full containers from being destroyed and reduce some copying overhead. was this a correct and valid assumption?
  2. why cant't I save a const-reference of tickDataBundle in the above queue? (MessageQueue<const tickDataBundle&> m_processed_data; generates error)

thank you

UPDATE: this part is JUST FOR YOUR REFERENCE I am copying the structure of my MessageQueue and the error I will get if I declare MessageQueue<const tickDataBundle&> m_processed_data;

template<class T>
class MessageQueue {
    std::queue<T> messageList;
    boost::shared_mutex mutex;
public:
    MessageQueue();
    virtual ~MessageQueue();
    bool ReadMessage();
    void post(T message);
    bool pop(T&);
    void clear();
    int size();
};

error:

In file included from /usr/include/c++/4.8/deque:64:0,
                     from /usr/include/c++/4.8/queue:60,
                     from ./ns3/drop-tail-queue.h:22,
                     from ./ns3/network-module.h:24,
                     from ../src/simmobility/examples/simmobility-RR-baseline.cc:2:
    /usr/include/c++/4.8/bits/stl_deque.h: In instantiation of ‘class std::_Deque_base<const sim_mob::RoadRunnerBaseLine::tickDataBundle&, std::allocator<const sim_mob::RoadRunnerBaseLine::tickDataBundle&> >’:
    /usr/include/c++/4.8/bits/stl_deque.h:730:11:   required from ‘class std::deque<const sim_mob::RoadRunnerBaseLine::tickDataBundle&, std::allocator<const sim_mob::RoadRunnerBaseLine::tickDataBundle&> >’
    /usr/include/c++/4.8/bits/stl_queue.h:96:46:   required from ‘class std::queue<const sim_mob::RoadRunnerBaseLine::tickDataBundle&, std::deque<const sim_mob::RoadRunnerBaseLine::tickDataBundle&, std::allocator<const sim_mob::RoadRunnerBaseLine::tickDataBundle&> > >’
    ./ns3/smb_message_queue.h:18:16:   required from ‘class sim_mob::MessageQueue<const sim_mob::RoadRunnerBaseLine::tickDataBundle&>’
    ./ns3/smb_roadrunner_baseline.h:87:47:   required from here
    /usr/include/c++/4.8/bits/stl_deque.h:448:60: error: forming pointer to reference type ‘const sim_mob::RoadRunnerBaseLine::tickDataBundle&’
           typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
                                                                ^
    /usr/include/c++/4.8/bits/stl_deque.h:449:60: error: forming pointer to reference type ‘const sim_mob::RoadRunnerBaseLine::tickDataBundle&’
           typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
                                                                ^
    /usr/include/c++/4.8/bits/stl_deque.h:488:61: error: forming pointer to reference type ‘const sim_mob::RoadRunnerBaseLine::tickDataBundle&’
           typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
    AND THE ERROR CONTINUES...

Upvotes: 0

Views: 134

Answers (1)

Charlie
Charlie

Reputation: 438

1. I figured if I make const-reference if the elements in the tickDataBundle, it will reduce some copying overhead. was this a correct and valid assumption?

The answer is yes. All copy of tickDataBundle objects only own the const reference of multicasts and agentsLocation, not coping real data in them.

*2. why cant't I save a const-reference of tickDataBundle in the above queue? (MessageQueue m_processed_data; generates error)*

The const reference must be assigned at the object construct time point. You can use const pointer as const reference, like this:

MessageQueue<const tickDataBundle*> m_processed_data;

Upvotes: 1

Related Questions