Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #87126 > unrolled thread

Is Copy-and-swap idiom too slow in assignment operator?

Started byJiiPee <kerrttuPoistaTama11@gmail.com>
First post2022-10-22 09:55 +0300
Last post2022-10-29 11:59 -0700
Articles 7 — 5 participants

Back to article view | Back to comp.lang.c++


Contents

  Is Copy-and-swap idiom too slow in assignment operator? JiiPee <kerrttuPoistaTama11@gmail.com> - 2022-10-22 09:55 +0300
    Re: Is Copy-and-swap idiom too slow in assignment operator? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-10-22 02:16 -0700
    Re: Is Copy-and-swap idiom too slow in assignment         operator? Sam <sam@email-scan.com> - 2022-10-22 07:50 -0400
      Re: Is Copy-and-swap idiom too slow in assignment operator? JiiPee <kerrttuPoistaTama11@gmail.com> - 2022-10-22 16:02 +0300
    Re: Is Copy-and-swap idiom too slow in assignment operator? Juha Nieminen <nospam@thanks.invalid> - 2022-10-24 07:10 +0000
      Re: Is Copy-and-swap idiom too slow in assignment operator? JiiPee <kerrttuPoistaTama11@gmail.com> - 2022-10-24 17:38 +0300
        Re: Is Copy-and-swap idiom too slow in assignment operator? Öö Tiib <ootiib@hot.ee> - 2022-10-29 11:59 -0700

#87126 — Is Copy-and-swap idiom too slow in assignment operator?

FromJiiPee <kerrttuPoistaTama11@gmail.com>
Date2022-10-22 09:55 +0300
SubjectIs Copy-and-swap idiom too slow in assignment operator?
Message-ID<tj0448$rtfp$3@dont-email.me>
In a class when defining an assignment operator:

operator=(const Obj& other)

, if one uses the Copy-and-swap idiom to copy @other to this:

Obj copy(other);
copy.swap(*this);

, this is obviously really good looking and elegant etc. But just 
wondering how much slower it would be than a straight/old (not so 
elegant/risky):

this->a = other.a;
this->b = other.b;
...

? I was just checking, if doing swap(), then needs to make 2 or 3 times 
more copy operations in total complare to old way for simple data types 
(int, float, double, bool...). If one has many of these, then is it 
gonna be much slower?

Or... is the compiler gonna optimize out these extra integer/double copy 
operations?

[toc] | [next] | [standalone]


#87128

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2022-10-22 02:16 -0700
Message-ID<tj0ce8$spig$1@dont-email.me>
In reply to#87126
On 10/21/2022 11:55 PM, JiiPee wrote:
> In a class when defining an assignment operator:
> 
> operator=(const Obj& other)
> 
> , if one uses the Copy-and-swap idiom to copy @other to this:
> 
> Obj copy(other);
> copy.swap(*this);
> 
> , this is obviously really good looking and elegant etc. But just 
> wondering how much slower it would be than a straight/old (not so 
> elegant/risky):
> 
> this->a = other.a;
> this->b = other.b;
> ...

With what kind of class? What is `a` and `b`?

If this is a flat class, then of course straightforward copying will be 
faster, since it requires only one copying, while copy-and-swap will 
copy the same data twice (or even thrice). The larger the class - the 
slower in comparison the copy-and-swap is going to be.

If this is a "deep" class that handles resources, which need to be 
copied, then in general case expenses spent on releasing the old 
resources and cloning new ones in copy constructor or assignment 
operator will dwarf the overhead brought in by swapping.

-- 
Best regards,
Andrey.

[toc] | [prev] | [next] | [standalone]


#87129 — Re: Is Copy-and-swap idiom too slow in assignment operator?

FromSam <sam@email-scan.com>
Date2022-10-22 07:50 -0400
SubjectRe: Is Copy-and-swap idiom too slow in assignment operator?
Message-ID<cone.1666439436.510136.302877.1004@monster.email-scan.com>
In reply to#87126
JiiPee writes:

> In a class when defining an assignment operator:
>
> operator=(const Obj& other)
>
> , if one uses the Copy-and-swap idiom to copy @other to this:
>
> Obj copy(other);
> copy.swap(*this);
>
> , this is obviously really good looking and elegant etc. But just wondering  
> how much slower it would be than a straight/old (not so elegant/risky):
>
> this->a = other.a;
> this->b = other.b;

For a simple class, copy/swap is an overkill. But for a complex class that  
contains many objects that also have their own bookkeeping, or their own  
special needs, then copy/swap offers a simple way to remove a lot of code  
duplication.

For example: if, for whatever reasons, a and b have a deleted assignment  
operator, but have functional copy/move semantics.

[toc] | [prev] | [next] | [standalone]


#87131

FromJiiPee <kerrttuPoistaTama11@gmail.com>
Date2022-10-22 16:02 +0300
Message-ID<tj0pkn$thva$1@dont-email.me>
In reply to#87129
On 22/10/2022 14:50, Sam wrote:
> For a simple class, copy/swap is an overkill.

could test how much slower it is. But its simple and elegant. And no 
need to then repeat code.

[toc] | [prev] | [next] | [standalone]


#87151

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-10-24 07:10 +0000
Message-ID<tj5dop$ccr$1@gioia.aioe.org>
In reply to#87126
JiiPee <kerrttuPoistaTama11@gmail.com> wrote:
> In a class when defining an assignment operator:
> 
> operator=(const Obj& other)
> 
> , if one uses the Copy-and-swap idiom to copy @other to this:
> 
> Obj copy(other);
> copy.swap(*this);
> 
> , this is obviously really good looking and elegant etc. But just 
> wondering how much slower it would be than a straight/old (not so 
> elegant/risky):
> 
> this->a = other.a;
> this->b = other.b;
> ...

It depends on the situation.

For example, suppose you are assigning one (object similar to) std::string
to another: If the target already has enough capacity to contain the
source string, then no new allocations will be needed and it's just
a simple straightforward string copy. If the copy-and-swap idiom had
been used here, a new dynamic memory allocation would have been done
and the existing one would have been deleted, for no good reason.

The difference becomes even more drastic with classes like std::list
(or any class with a similar functionality): If the target already
has elements in it, then assigning can just assign the source elements
onto the existing target elements, thus avoiding unneeded extra
allocations. The copy-and-swap idiom would make dynamic allocations
for every single element to be copied, and then delete the existing
ones, for no reason.

Of course in other situations it doesn't really make much of a
difference.

[toc] | [prev] | [next] | [standalone]


#87153

FromJiiPee <kerrttuPoistaTama11@gmail.com>
Date2022-10-24 17:38 +0300
Message-ID<tj6819$1mv4m$1@dont-email.me>
In reply to#87151
On 24/10/2022 10:10, Juha Nieminen wrote:
> It depends on the situation.

good answer. good point. yes not blindly following a given rule.
But, I wonder why on those videos those expects do not mention so much 
about this but its like "this is the elegant way to do it"?

[toc] | [prev] | [next] | [standalone]


#87176

FromÖö Tiib <ootiib@hot.ee>
Date2022-10-29 11:59 -0700
Message-ID<65286ded-0afa-4939-97bc-777783a538d5n@googlegroups.com>
In reply to#87153
On Monday, 24 October 2022 at 17:38:50 UTC+3, JiiPee wrote:
> On 24/10/2022 10:10, Juha Nieminen wrote: 
> > It depends on the situation.
> good answer. good point. yes not blindly following a given rule. 
> But, I wonder why on those videos those expects do not mention so much 
> about this but its like "this is the elegant way to do it"?

It is because swap does not (have conceivable reasons to) throw and
so there are no way that copy and swap trashes the object of this.

OTOH when this->b = other.b;  throws then this->a is tricky to return to
what it was. So your straight/old assignment is actually bad/naive
in language with exceptions.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web