New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use move instead of copy in vector::insert()/set_capacity() #66
Conversation
6f518df
to
0b73b4d
Compare
Thanks for submitting this PR. Please include a test that highlights the issue and demonstrates that it is resolved by your change. The code you provided as an example is a good start. I'd recommend reading the existing test code in EASTL that uses 'TestObject' as an example of what I'm looking for. 'TestObject' is a test utility that counts the calls to the various constructors and operators and it is used to validate the behaviour of EASTL containers. Example: |
Hi, Note that existing tests was failing with my first implementation of set_capacity(), but the continuous integration, did not failed (see: https://ci.appveyor.com/project/rparolin/eastl/build/1.0.128/job/jsfvpy3au5r1p095#L758). The executable test return code 1 (https://ci.appveyor.com/project/rparolin/eastl/build/1.0.128/job/jsfvpy3au5r1p095#L863), but after that EASTLBenchmarks.exe was launched and return 0. And it seems that it's only this last error code which is used. About tests, I also add few #if EASTL_MOVE_SEMANTICS_ENABLED/#endif in TestVector.cpp in order to be able to build without this define. Tell me if you see some problem or have remark about the code or test. |
I JUST noticed that myself. I guess I have to add 'bundle' commands to my .travis.yml file. Thanks for bringing that up. https://docs.travis-ci.com/user/customizing-the-build/#Customizing-the-Build-Step |
@@ -1453,6 +1520,7 @@ int TestVector() | |||
// unique_ptr tests | |||
{ | |||
// Simple move-assignment test to prevent regressions where eastl::vector utilizes operations on T that are not necessary. | |||
#if EASTL_MOVE_SEMANTICS_ENABLED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please align pre-processor conditionals with the braces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I have recommit this part, moving the pre-processor on the previous line in order to have the same style has the other cases.
temp.mpBegin = pNewData; | ||
temp.mpEnd = pNewEnd; | ||
temp.mpCapacity = pNewEnd; | ||
#else | ||
this_type temp(*this); // This is the simplest way to accomplish this, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe previously you simply utilized vector's move constructor. What was the problem with that implementation? I don't believe this above is required to be written explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, in my first implementation, I just used the move constructor with eastl::move(). With that, I have few UnitTest failed, because the move was done on the buffer, not one each element, so the the allocation at the end stays with the exact same size!
While the set_capicity() ask to reduce the size of the buffer/container to fit the size, it was not correct.
I'm agree that this implementation is quite long, and perhaps there is other internal vector I could call to reduce the code size. If you have idea for that, tell me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take a look at the 'shrink_to_fit' implementation. It utilizes the vector constructor which takes a pair of iterators (begin, end) and passes move iterators to that constructor.
#if EASTL_MOVE_SEMANTICS_ENABLED
this_type temp = this_type(move_iterator<iterator>(begin()), move_iterator<iterator>(end()), mAllocator);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed shrink_to_fit() function seems to do the job. And the exact same job as it's needed here. So I remove the part of code which create a temp vector and swap it and just call shrink_to_fit().
Tell me if it's all ok for you.
…_capacity() * TestVector: add tests to check move in vector::insert() and vector::set_capacity() * TestVector: add #if EASTL_MOVE_SEMANTICS_ENABLED/endif for test which use move semantic
Thanks for the PR. :) |
In vector::insert() and vector::set_capacity(), a copy is made on existing elements. Use move semantic in order to avoid copy when elements are moved or vector resize.
Here an example of code which show the extra copy done:
Here the associated issue: #67