AnswerBun.com

std::map::operator[] is more efficient than std::map::insert?

I’ve learnt that operator[] is equivalent to

(*((this->insert(make_pair(k,mapped_type()))).first)).second

So if a key doesn’t exist in the map, using operator[] is less efficient than using insert, right? Because there’s one more step, default construct.

So I wrote a demo to test, like this.


#include <iostream>
#include <map>

using namespace std;

static int id = 0;

class Foo
{
public:
    Foo()
        : _val(0)
    {
        _id = ++id;
        cout << _id << " construct_no_param:" << _val << endl;
    }
    Foo(int val)
        : _val(val)
    {
        _id = ++id;
        cout << _id << " construct_has_param:" << _val << endl;
    }
    Foo(Foo &rhs)
        : _val(rhs._val)
    {
        _id = ++id;
        cout << _id << " construct_copy:" << _val << endl;
    }
    Foo(const Foo &rhs)
        : _val(rhs._val)
    {
        _id = ++id;
        cout << _id << " construct_const_copy:" << _val << endl;
    }
    Foo &operator=(Foo &rhs)
    {
        _val = rhs._val;
        cout << _id << " assign:" << _val << endl;
    }
    Foo &operator=(const Foo &rhs)
    {
        _val = rhs._val;
        cout << _id << " const_assign:" << _val << endl;
    }
    ~Foo()
    {
        cout << _id << " destruct:" << _val << endl;
    }

    int _val;
    int _id;
};

int main() {
    map<int, Foo> m;
    const Foo f(2);
    cout << "-----" << endl;
    // m[1] = f;
    // m.insert(make_pair(1, f));
    cout << "-----" << endl;
    return 0;
}

First, I used operator[]

    m[1] = f;

And I got this:

1 construct_has_param:2
-----
2 construct_no_param:0
3 construct_const_copy:0
4 construct_const_copy:0
3 destruct:0
2 destruct:0
4 assign:2
-----
1 destruct:2
4 destruct:2

Then, I used insert

    m.insert(make_pair(1, f));

And I got this:

1 construct_has_param:2
-----
2 construct_const_copy:2
3 construct_const_copy:2
4 construct_const_copy:2
5 construct_const_copy:2
4 destruct:2
3 destruct:2
2 destruct:2
-----
1 destruct:2
5 destruct:2

The results are not correspond to what I’m expected. Why insert has more constructions? What’s going on here?

BTW, I use -O0 option to disable optimization, but I’m not sure if it works.

gcc version 4.8.2 20131212 (Red Hat 4.8.2-8) (GCC)

Stack Overflow Asked by EddieIpeace on December 27, 2020

1 Answers

One Answer

The expression make_pair(1, f) has type std::pair<int, Foo>, which isn't your maps value_type, which is std::pair<const int, Foo>, so there is a copy in the arguments of insert. There then are 2 copies within map, that would be moves if all your special members didn't suppress the generation of move construction.

If you want to avoid as much copying as you can, use emplace

m.emplace(1, f);

and define Foo's move constructor and assignment

Foo(Foo &&rhs)
    : _val(std::exchange(rhs.val, 0))
{
    _id = ++id;
    cout << _id << " move:" << _val << endl;
}

Foo& opeator=(Foo &&rhs)
{
    std::swap(_val, rhs._val);
    cout << _id << " move assign:" << _val << endl;
}

I would also recommend dropping the non-const copy operations.

Correct answer by Caleth on December 27, 2020

Add your own answers!

Related Questions

C# find the greatest common divisor

11  Asked on January 5, 2022 by user2723261

   

Time series summary

2  Asked on January 5, 2022 by naanan_

     

Compute frequencies for groups of variables

3  Asked on January 5, 2022 by armel-tedjou

       

How to plot entropart Diversity profiles in ggplot2

1  Asked on January 5, 2022 by alejandra-dip

   

Laravel 6.4.1 SQLSTATE[HY000] [2002] Connection refused

12  Asked on January 5, 2022 by manish-mahajan

         

How to get the key of an element in firebase with AngularFire2?

1  Asked on January 5, 2022 by juan-esteban-rios-gonzalez

         

(PowerShell) How do I filter usernames with Get-EventLog

3  Asked on January 5, 2022 by jeremiah-williams

     

pandas isin() fail between dataframes with objects types columns

1  Asked on January 5, 2022 by franco-milanese

     

Ask a Question

Get help from others!

© 2022 AnswerBun.com. All rights reserved.