Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

adding items to a map

0 views
Skip to first unread message

Priyesh

unread,
Oct 18, 2004, 1:58:42 PM10/18/04
to
what would be an efficient way to add items to a map from the choices below?
1. map[key] = value ;
2. map.insert(MAPTYPE::value_type(key, value)) ;

or is there any i am missing here which would be better?

Thanks in advance


Igor Tandetnik

unread,
Oct 18, 2004, 2:32:58 PM10/18/04
to
"Priyesh" <PriyeshPa...@cougarmtn.com> wrote in message
news:upOAAzTt...@TK2MSFTNGP10.phx.gbl

> what would be an efficient way to add items to a map from the choices
> below? 1. map[key] = value ;
> 2. map.insert(MAPTYPE::value_type(key, value)) ;

There is no measurable difference between the two if the key is not
currently present in the map. If the key is already present in the map,
then the first statement overwrites the value associated with it,
whereas the second does nothing (but its return value lets you know
whether or not the insertion occurred).
--
With best wishes,
Igor Tandetnik

"On two occasions, I have been asked [by members of Parliament], 'Pray,
Mr. Babbage, if you put into the machine wrong figures, will the right
answers come out?' I am not able to rightly apprehend the kind of
confusion of ideas that could provoke such a question." -- Charles
Babbage


Priyesh

unread,
Oct 18, 2004, 3:00:11 PM10/18/04
to
Thanks!

"Igor Tandetnik" <itand...@mvps.org> wrote in message
news:Oxr$eDUtE...@TK2MSFTNGP11.phx.gbl...

Jason Winnebeck

unread,
Oct 18, 2004, 5:00:48 PM10/18/04
to

Theoritically I think the second way is faster, because in the first
case an element is constructed with the default constructor, then the
new value is copied in with operator =. I'm not sure if the compiler is
at liberty to optimize the first method and just call the copy constructor.

Jason

Carl Daniel [VC++ MVP]

unread,
Oct 18, 2004, 5:10:14 PM10/18/04
to

For the second method the value_type (std::pair<key,value>) is constructed
(in the call) and then copy-constructed if a node is inserted, so it's not
clear to me if there's any reason to belive that one will be consistently
faster than the other. If the value is a type that is expensive to create
and copy but inexpensive to default-construct, then it's likely that the
first method will be more efficient, seems to me.

-cd


Igor Tandetnik

unread,
Oct 18, 2004, 5:12:03 PM10/18/04
to
"Jason Winnebeck" <gil...@mail.rit.nspam.edu> wrote in message
news:OB5JMWVt...@TK2MSFTNGP12.phx.gbl

> Priyesh wrote:
>> what would be an efficient way to add items to a map from the
>> choices below? 1. map[key] = value ;
>> 2. map.insert(MAPTYPE::value_type(key, value)) ;
>
> Theoritically I think the second way is faster, because in the first
> case an element is constructed with the default constructor, then the
> new value is copied in with operator =.

... But note how in the example provided, an extra temporary copy of
both key and value are constructed as part of MAPTYPE::value_type, then
copy-constructed into the map's node. I'm not sue there's a way to call
map::insert() in a way that avoids these extra copies.

> I'm not sure if the compiler
> is at liberty to optimize the first method and just call the copy
> constructor.

I don't think so - not at the C++ semantic level. Of course if the
compiler can inline both the default constructor and the assignment
operator, and see that there are no side effects, it can blend the two
together, possibly optimizing large pieces away in the process.

Tom Widmer

unread,
Oct 19, 2004, 5:23:00 AM10/19/04
to

We need rvalue references!

Tom

Carl Daniel [VC++ MVP]

unread,
Oct 19, 2004, 3:52:38 PM10/19/04
to
"Tom Widmer" <tom_u...@hotmail.com> wrote in message
news:l5n9n01ustucl28nr...@4ax.com...
>
> We need rvalue references!

Here here!

-cd


Stephen Howe

unread,
Oct 28, 2004, 11:00:17 AM10/28/04
to
>>> 1. map[key] = value ;
>>> 2. map.insert(MAPTYPE::value_type(key, value)) ;

> There is no measurable difference between the two if the key is not
> currently present in the map.

Yes there is. I went away and measured it with VC7.1.

See the bottom of
http://www.google.com/groups?hl=en&lr=&safe=off&selm=uD4yVyAeBHA.2284%40tkmsftngp05&rnum=9

But I decided that what I tested was not sufficiently comprehensive enough.

So doing (please view using "Courier New", a fixed-width font so everything
lines up)

(i) use map.insert(make_pair(key,value));
(ii) use map.insert(pair(key,value));
(iii) use map.insert(map::value_type(key,value));
(iv) use map.insert(p); where p is a pre-built pair
(v) use map[key] = value;
(vi) use map.insert(p); where p is a pre-built pair and there is
already a key in the map
(vii) use map[key] = value; where there is already a key in the map

I see operations

key value
ctor cctor dtor ctor cctor dtor assign op
(i) - 4 3 - 4 3 -
(ii) - 3 2 - 3 2 -
(iii) - 2 1 - 2 1 -
(iv) - 2 1 - 2 1 -
(v) - 2 1 1 2 2 1
(vi) - 1 1 - 1 1 -
(vii) - - - - - - 1

So there is no difference between inserting doing (iii) or (iv) but using
(v) there is extra constructor, assignment operator and destructor for the
value.

For the "successful insertion" cases (i) to (v), the total number of ctors -
dtors is always 1 as of course you wind up with a key,value pair in the map.

(iii) and (iv) are the most efficient (and best still with a good iterator
hint)

Here is test code

>>>>>>>>>>>>>>
#include <map>
#include <string>
#include <iomanip>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <utility>

using namespace std;

class Key
{
public:
Key(const char *sz) : sData(sz)
{
if (bVerbose) cout << "Key const C-string ctor\n";
}
Key(char *sz) : sData(sz)
{
if (bVerbose) cout << "Key C-string ctor\n";
}
Key(const string &s) : sData(s)
{
if (bVerbose) cout << "Key const string ctor\n";
}
Key()
{
if (bVerbose) cout << "Key dflt ctor\n";
}
~Key()
{
if (bVerbose) cout << "Key dtor\n";
}
Key(const Key &rhs) : sData(rhs.sData)
{
if (bVerbose) cout << "Key copy ctor\n";
}
Key &operator = (const Key &rhs)
{ sData = rhs.sData;
if (bVerbose) cout << "Key assignment\n";
return *this;
}
bool operator < (const Key &rhs) const
{
return (sData < rhs.sData);
}
static void VerboseOn() { bVerbose = true; }
static void VerboseOff() { bVerbose = false; }

private:
string sData;
static bool bVerbose;
};

class Value
{
public:
Value(const char *sz) : sData(sz)
{
if (bVerbose) cout << "Value const C-string ctor\n";
}
Value(char *sz) : sData(sz)
{
if (bVerbose) cout << "Value C-string ctor\n";
}
Value(const string &s) : sData(s)
{
if (bVerbose) cout << "Value const string ctor\n";
}
Value()
{
if (bVerbose) cout << "Value dflt ctor\n";
}
~Value()
{
if (bVerbose) cout << "Value dtor\n";
}
Value(const Value &rhs) : sData(rhs.sData)
{
if (bVerbose) cout << "Value copy ctor\n";
}
Value &operator = (const Value &rhs)
{ sData = rhs.sData;
if (bVerbose) cout << "Value assignment\n";
return *this;
}
static void VerboseOn() { bVerbose = true; }
static void VerboseOff() { bVerbose = false; }
private:
string sData;
static bool bVerbose;
};

bool Key::bVerbose;
bool Value::bVerbose;

static void VerboseOn()
{
Key::VerboseOn();
Value::VerboseOn();
}

static void VerboseOff()
{
Key::VerboseOff();
Value::VerboseOff();
}

int main(void)
{
VerboseOff();
map<Key, Value> m;
Key t1("a");
Key t2("b");
Key t3("c");
Value tv("d");
Value tv2("e");
pair<Key, Value> p(t3, tv);

//
// === make_pair test
//
VerboseOn();
cout << "make_pair test Start\n";
m.insert(make_pair(t1, tv));
cout << "make_pair test Stop\n\n";
VerboseOff();

m.clear();

//
// === pair test
//
VerboseOn();
cout << "pair test Start\n";
m.insert(pair<Key, Value>(t2, tv));
cout << "pair test Stop\n\n";
VerboseOff();

m.clear();

//
// === value_type test
//
VerboseOn();
cout << "value_type test Start\n";
m.insert(map<Key, Value>::value_type(t2, tv));
cout << "value_type test Stop\n\n";
VerboseOff();

m.clear();

//
// === pre-formed pair test
//
VerboseOn();
cout << "pre-formed pair test Start\n";
m.insert(p);
cout << "pre-formed pair test Stop\n\n";
VerboseOff();

m.clear();

//
// === [] test insert
//
VerboseOn();
cout << "[] test insert Start\n";
m[t2] = tv;
cout << "[] test insert Stop\n\n";
VerboseOff();

m.clear();

//
// === pre-formed pair test - insert failure
//
m.insert(p);
VerboseOn();
cout << "pre-formed pair failure test Start\n";
m.insert(p);
cout << "pre-formed pair failure test Stop\n\n";
VerboseOff();

m.clear();

//
// === [] test insert
//
m[t2] = tv;
VerboseOn();
cout << "[] test update Start\n";
m[t2] = tv2;
cout << "[] test update Stop\n\n";
VerboseOff();

m.clear();

return 0;
}
>>>>>>>>>>>>>>

Stephen Howe


Priyesh

unread,
Oct 28, 2004, 7:37:58 PM10/28/04
to
Thanks!

"Stephen Howe" <stephenPOINThoweATtns-globalPOINTcom> wrote in message
news:OLBPY7Pv...@TK2MSFTNGP15.phx.gbl...

0 new messages