Quantcast

[TypeErasure] efficiency problem

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[TypeErasure] efficiency problem

Boost - Users mailing list
Hello!

In following code TypeErasure creates two copies of s, while Boost.Any
creates no copies at all.

any x{ s{} };
any y{ std::move(x) };
any z;
z = std::move(y);

There is move constructor for type_erasure::any, but it does allocate
memory and calls copy constructor for s. Why?

And why there is no move assignment operator in type_erasure::any?

Thanks.

Full source: https://wandbox.org/permlink/iHs5a0bjzXsBtpwC
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [TypeErasure] efficiency problem

Boost - Users mailing list
Am 23.03.2017 um 06:55 schrieb Mikhail Strelnikov via Boost-users:

> Hello!
>
> In following code TypeErasure creates two copies of s, while Boost.Any
> creates no copies at all.
>
> any x{ s{} };
> any y{ std::move(x) };
> any z;
> z = std::move(y);
>
> There is move constructor for type_erasure::any, but it does allocate
> memory and calls copy constructor for s. Why?

I am not really sure, but I investigated this over a year ago and I
think the problem was either that no real move-constructor was
implemented or the wrong constructor overload was taken. (I think,
taking the wrong overload happened at least in some of my personal
test-cases back then. The constructor with the "universal reference" [1]
very often better matched the inputs than some of the overloads.)

> And why there is no move assignment operator in type_erasure::any?

A pull-request to Boost.TypeErasure exists [2] which adds support for
move-assignment. (I wrote this about a year ago and we have been using
it successfully in production-code at our company for over half a year now.)
However, this pull-request seems to have been overlooked by the author
of Boost.TypeErasure.

If you do not mind using a patched version of Boost.TypeErasure you
could apply this pull-request to your local version of Boost and use that.
Of course, I would prefer if this pull-request (or some other
pull-request adding move-assignment support) would make it into the
official version of Boost.TypeErasure.

Hope that helps,
Deniz

[1] https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
[2] https://github.com/boostorg/type_erasure/pull/12

>
> Thanks.
>
> Full source: https://wandbox.org/permlink/iHs5a0bjzXsBtpwC
> _______________________________________________
> Boost-users mailing list
> [hidden email]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [TypeErasure] efficiency problem

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
AMDG

On 03/22/2017 11:55 PM, Mikhail Strelnikov via Boost-users wrote:
>
> In following code TypeErasure creates two copies of s, while Boost.Any
> creates no copies at all.
>
> any x{ s{} };
> any y{ std::move(x) };

  Boost.TypeErasure tries to be as faithful as possible
to normal overload resolution rules.  As a result,
the move constructor should resolve as follows:
If constructible<P(P&&)> is present
  Allocate a new object and call the captured move
  constructor to initialize it.
Else if constructible<P(const P&)> is present
  Allocate a new object and initialize it with the
  copy constructor.
Else
  Error

  If relaxed is present, then it would be possible
to move the pointer, leaving the source any empty,
but this isn't currently implemented.

> any z;
> z = std::move(y);
>
> There is move constructor for type_erasure::any, but it does allocate
> memory and calls copy constructor for s. Why?
>
> And why there is no move assignment operator in type_erasure::any?
>

There will be once I get around to merging Deniz' PR.

In Christ,
Steven Watanabe

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [TypeErasure] efficiency problem

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
I had to change the declaration of my any to:

using any = boost::type_erasure::any<mpl::vector<constructible<_self(_self&&)>,
assignable<_self, _self&&>, destructible<_self>, typeid_<>, relaxed>
>;

And then I've tried your patch, it works, thanks.

But it solves only half of the problem - there is still memory
allocation happening every time type_erasure::any is move-constructed
or move-assigned (again, there are no extra memory allocations in this
case when Boost.Any is used).

2017-03-23 15:10 GMT+03:00 Deniz Bahadir via Boost-users
<[hidden email]>:

> Am 23.03.2017 um 06:55 schrieb Mikhail Strelnikov via Boost-users:
>>
>> Hello!
>>
>> In following code TypeErasure creates two copies of s, while Boost.Any
>> creates no copies at all.
>>
>> any x{ s{} };
>> any y{ std::move(x) };
>> any z;
>> z = std::move(y);
>>
>> There is move constructor for type_erasure::any, but it does allocate
>> memory and calls copy constructor for s. Why?
>
>
> I am not really sure, but I investigated this over a year ago and I think
> the problem was either that no real move-constructor was implemented or the
> wrong constructor overload was taken. (I think, taking the wrong overload
> happened at least in some of my personal test-cases back then. The
> constructor with the "universal reference" [1] very often better matched the
> inputs than some of the overloads.)
>
>> And why there is no move assignment operator in type_erasure::any?
>
>
> A pull-request to Boost.TypeErasure exists [2] which adds support for
> move-assignment. (I wrote this about a year ago and we have been using it
> successfully in production-code at our company for over half a year now.)
> However, this pull-request seems to have been overlooked by the author of
> Boost.TypeErasure.
>
> If you do not mind using a patched version of Boost.TypeErasure you could
> apply this pull-request to your local version of Boost and use that.
> Of course, I would prefer if this pull-request (or some other pull-request
> adding move-assignment support) would make it into the official version of
> Boost.TypeErasure.
>
> Hope that helps,
> Deniz
>
> [1] https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
> [2] https://github.com/boostorg/type_erasure/pull/12
>
>>
>> Thanks.
>>
>> Full source: https://wandbox.org/permlink/iHs5a0bjzXsBtpwC
>> _______________________________________________
>> Boost-users mailing list
>> [hidden email]
>> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>>
> _______________________________________________
> Boost-users mailing list
> [hidden email]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Loading...