Apr 19, 2013 at 6:05pm UTC
buffer b = socket_receive();
does not compile, because you didn't observe const correctness.
buffer(const buffer& b) : data(b.data) {}
or better, don't do anything as the compiler already provides that constructor.
> there is a copy constructor, and the tmp variable is constructed and destructed
RVO
By the way, `clock()' does not measure ms.
Apr 19, 2013 at 6:20pm UTC
Lines 31 and 32 do exactly the same thing.
You aren't compiling with optimzations enabled.
If you are using VC++ (where no implicit move constructor/assignment operators are implemented,) the small string optimization will be in effect for your small string and performance will not be improved by using move semantics for them.
You can find an explanation here:
http://john-ahlgren.blogspot.com/2012/03/small-string-optimization-and-move.html
That said, I would expect RVO here would make either method equally fast. This seems to be born out by the following test (with optimizations enabled):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;
struct bufferA {
std::string data ;
bufferA() {}
bufferA(const bufferA& buffer) : data(buffer.data) {}
bufferA(bufferA&& buffer) : data(std::move(buffer.data)) {}
bufferA(const char * d) : data(d) {}
bufferA& operator =(bufferA&& b)
{
data = std::move(b.data) ;
return *this ;
}
};
struct bufferB {
std::string data ;
bufferB() {}
bufferB(const char * d) : data(d) {}
};
const char * strings[] =
{
"1234aasldkfja;oij;laskdjfa;lsdjf;alskdjfasdfa;slkdfja;lskdjf;alskdjf" ,
"abcd;alskjdf;alisdjf;alskdjf;alskdjf;alskdjf;alskdjflkjleijalvknadsf" ,
"efgh;lkjeaoic;aliej;lkajv;lijea;lksjd;laijea;lkejav;lkansdl;kreaa;lk" ,
"ijkl;lkaj389jalkd089ua3/mnzvo;8erja/knCVosj8ia[8ejralkdcvjnao8j3ea3d"
};
unsigned stringsElements = sizeof (strings) / sizeof (strings[0]) ;
bufferA receiveA()
{
return bufferA(strings[std::rand()%stringsElements]) ;
}
bufferB recieveB()
{
return bufferB(strings[std::rand()%stringsElements]) ;
}
const unsigned testIterations = 2000000 ;
int main() {
std::srand(static_cast <unsigned >(std::time(0))) ;
auto beg = clock();
for (unsigned i=0; i<testIterations; ++i) {
bufferA buffer = receiveA();
}
auto end = clock() ;
cout << "time passed: " << (end-beg) << "ms" << endl;
beg = clock() ;
for ( unsigned i=0; i< testIterations; ++i )
{
bufferB buffer = recieveB() ;
}
end = clock() ;
std::cout << "time passed: " << (end-beg) << "ms" << endl ;
}
Output:
time passed: 390ms
time passed: 390ms
Last edited on Apr 19, 2013 at 6:33pm UTC
Apr 19, 2013 at 7:55pm UTC
The RVO looks interesting, seems the compiler already did everything.
Thanks for the explanation, and the tip of 'clock' and 'small string'.