I am writing a couple string sort algorithm with c++ and I wonder if I can make this swap operation faster.
void swap(string *items,int a, int b ){
string temp;
temp = items[a];
items[a] = items[b];
items[b] = temp;
}
I'll be appreciate if you can help...
String class has its own swap function.
items[a].swap(items[b]);
It's the fastest way to do this because it accesses the string internals and avoids all copying.
See here.
You can use std::swap():
void swap(string *items, int a, int b) {
std::swap(items[a], items[b]);
}
But there's no guarantee that this will be measurably faster, and this probably isn't the slow part of your code anyway. Have you measured the performance of the swap operation compared to the rest of your code?
Use std::swap; it will do the best job it can. If your compiler supports C++11's rvalue references, this means that it will take advantage of move semantics to avoid the copy that occurs in your swap function.
However, if your compiler doesn't support rvalue references, it will most likely perform the same way as your swap function does.
Most standard library implementations will implement std::swap as something similar to:
template<typename T>
void swap(T& a, T& b) {
T temp(std::move(a));
a = std::move(b);
b = std::move(temp);
}
The std::move function will return an rvalue reference (T&&) to the variable passed in. When you attempt to assign this rvalue reference, it will invoke the type's move operator, if one is available. If a move operator isn't available, it will invoke the copy operator as usual.
In the case of std::string, the above swap function will do no string copies with C++11; only the internal data, such as the string length and C string pointer, will be copied. Without C++11, it will perform three copies of the actual string contents.
You could change your algorithm to work on elements of type string* instead of string. Then all the assignments in your swap function would operate on pointers, and be faster because no string copying would be involved.
Related
This is probably pretty similar to other questions; I looked around a bit but I don't know what I'm talking about well enough to be sure.
I'm writing a function that "should" be in-place, but which is implemented by a BLAS call. The BLAS call is not in-place so I need to make a temporary. Thus:
void InPlace(ArrayClass& U, const TransformMatrix* M){
ArrayClass U_temp;
CallBLASdgemm(U, M, U_temp); //Now U_temp contains the correct output.
U = std::move(U_temp);
}
Is this a valid use of std::move, or am I somehow breaking "copy elision" (or is it bad for some other reason)?
Edit: the signature of CallBLASDgemm was requested; it is
CallBLASdgemm(const ArrayClass& U, const TransformMatrix* M,
ArrayClass& V);
No copies are performed with or without copy elision in this case so that's already out of the question. Because U_temp is an lvalue the compiler has to call the copy constructor if you'd do :
U = U_temp;
However, you know that U_temp won't be used anymore and thus moving away its values is completely safe and can possibly be faster (that is, if ArrayClass implements a move assignment constructor). Using std::move here is fine and even encouraged.
Yes, this is a valid use case. If you have a named temporary (lvalue) the only way to move it into U is to use std::move to cast it to a rvalue.
I think what you are worried about is when people do return std::move(object);. That is a pessimization as that copy of object into the return value can be elided in most cases.
This is valid. However, what I'd do is this:
ArrayClass myCallBLASdgemm(const ArrayClass& U, const TransformMatrix* M) {
ArrayClass tmp;
CallBLASdgemm(U, M, tmp);
return tmp; // elided move
}
void InPlace(ArrayClass& U, const TransformMatrix* M){
U = myCallBLASdgemm(U, M);
}
which runs the same code, but does it without a temporary being visible in the outer scope.
In fact, myCallBLASdgemm is so clean you can probably eliminate InPlace and just call myClassBLASdgemm where you need it.
In python we can swap two variables as
>>> a , b = b , a
We can do similar kind of swapping in C++11 as
void swap(int &a,int &b)
{
std::tie(a,b) = std::make_tuple(b,a);
}
Above works fine, and at O3 generates similar assembly as
void swap(int &a,int &b)
{
int c = a;
a = b;
b = c;
}
But my question is it conforming to standards or I am missing something?
Or is it a fluke like...
a = (a+b) - (b=a);
Which has sequence point issue.
This is fine.
The calls to std::tie and std::make_tuple could occur in any order, but they don't modify a and b, only create std::tuples with references to and copies of a and b, respectively. It's only when operator= is invoked that any modifications are made through the assigning of the references.
There is std::swap for this. It has a default implementation of swapping the values by using a temporary value, but for some types (e.g. standard containers) it has an optimized implementation.
Here is some more information: http://en.cppreference.com/w/cpp/algorithm/swap
In C++ you can use the std::swap() template like so:
#include <algorithm>
...
std::swap(a,b);
Note that in C++11 it is declared in the <utility> header file.
Your code moves if possible - else copies - both values into the tuple temporary, then copies them back out to the moved-/copied-from variables. It will work safely for types where those operations have their usual semantics, but may be inefficient for more complex user-defined types. It obviously requires the types support the move or copy-construction and assignments used. (Specifically, the assignment only happens after the tuple members are set, and if the type has value semantics then at the time of assignment the moved- or copied-from objects being assigned are independent from the values in the tuple).
Where available for the type involved, using the Standard Library's std::swap is the best option. Many other types may provide a swap overload that's optimal for them. If you want a conceptually simple way to create custom swap functions for your own types, you could use the code you've shown subject to the cons mentioned above.
Usually I use this to avoid copying cost:
void bar(const string& s);
void foo(const vector<int>& v);
Are STL containers in C++11 all support move semantics?
If so, does following code have the same performance as const &?
void bar(string s);
void foo(vector<int> v);
Move semantics don't just magically make your code faster.
With them, calling a function like void bar(string s) is faster than it would be if you had to copy your arguments, but only in the case where the argument can be moved. Consider this case:
std::string prompt(std::string prompt_text);
void askOnce(std::string question) { prompt(question); }
void askManyTimes(std::string question) {
for(int i=0; i<10; ++i) {
askOnce(question);
}
}
In the case of askOnce, the argument can be copied into the function or moved. When it's calling prompt, the argument can be moved.
In askManyTimes however, you need to keep the argument around so you can't move, so you actually end up having to create 10 copies of your question for no good reason.
Generally, if you don't need to modify your string or copy it somewhere else, you should still use const std::string&; You can leave the reference off if you need to do a copy later on anyway.
Are STL containers in C++11 all support move semantics?
Yes.
If so, does following code have the same performance as const &?
No, if the argument is an lvalue. If the argument is an rvalue, the performance is at least as good.
In the case of an lvalue, the argument has to be copied. There's no way around that. The function signature specifies that it doesn't modify its arguments, but a move operation might modify the object that is being moved from.
In the case of an rvalue, the argument can be moved from, if supported.
So if the parameter will be copied inside the function anyway, it is better to pass it by value, so that rvalues can be moved from, while lvalues will still be copied.
It depends what you pass in. If you pass a temporary object it will get moved in but if you pass a named variable it will get copied.
bar(func_returns_string()); // move
std::string s;
bar(s); // copy
You can force it to move a named variable using std::move:
bar(std::move(s)); // move (now s is empty)
Since const reference is pretty much the same as passing by value but without creating a copy (to my understanding). So is there a case where it is needed to create a copy of the variables (so we would need to use pass by value).
There are situations where you don't modify the input, but you still need an internal copy of the input, and then you may as well take the arguments by value. For example, suppose you have a function that returns a sorted copy of a vector:
template <typename V> V sorted_copy_1(V const & v)
{
V v_copy = v;
std::sort(v_copy.begin(), v_copy.end());
return v;
}
This is fine, but if the user has a vector that they never need for any other purpose, then you have to make a mandatory copy here that may be unnecessary. So just take the argument by value:
template <typename V> V sorted_copy_2(V v)
{
std::sort(v.begin(), v.end());
return v;
}
Now the entire process of producing, sorting and returning a vector can be done essentially "in-place".
Less expensive examples are algorithms which consume counters or iterators which need to be modified in the process of the algorithm. Again, taking those by value allows you to use the function parameter directly, rather than requiring a local copy.
It's usually faster to pass basic data types such as ints, floats and pointers by value.
Your function may want to modify the parameter locally, without altering the state of the variable passed in.
C++11 introduces move semantics. To move an object into a function parameter, its type cannot be const reference.
Like so many things, it's a balance.
We pass by const reference to avoid making a copy of the object.
When you pass a const reference, you pass a pointer (references are pointers with extra sugar to make them taste less bitter). And assuming the object is trivial to copy, of course.
To access a reference, the compiler will have to dereference the pointer to get to the content [assuming it can't be inlined and the compiler optimises away the dereference, but in that case, it will also optimise away the extra copy, so there's no loss from passing by value either].
So, if your copy is "cheaper" than the sum of dereferencing and passing the pointer, then you "win" when you pass by value.
And of course, if you are going to make a copy ANYWAY, then you may just as well make the copy when constructing the argument, rather than copying explicitly later.
The best example is probably the Copy and Swap idiom:
C& operator=(C other)
{
swap(*this, other);
return *this;
}
Taking other by value instead of by const reference makes it much easier to write a correct assignment operator that avoids code duplication and provides a strong exception guarantee!
Also passing iterators and pointers is done by value since it makes those algorithms much more reasonable to code, since they can modify their parameters locally. Otherwise something like std::partition would have to immediately copy its input anyway, which is both inefficient and looks silly. And we all know that avoiding silly-looking code is the number one priority:
template<class BidirIt, class UnaryPredicate>
BidirIt partition(BidirIt first, BidirIt last, UnaryPredicate p)
{
while (1) {
while ((first != last) && p(*first)) {
++first;
}
if (first == last--) break;
while ((first != last) && !p(*last)) {
--last;
}
if (first == last) break;
std::iter_swap(first++, last);
}
return first;
}
A const& cannot be changed without a const_cast through the reference, but it can be changed. At any point where code leaves the "analysis range" of your compiler (maybe a function call to a different compilation unit, or through a function pointer it cannot determine the value of at compilation time) it must assume that the value referred to may have changed.
This costs optimization. And it can make it harder to reason about possible bugs or quirks in your code: a reference is non-local state, and functions that operate only on local state and produce no side effects are really easy to reason about. Making your code easy to reason about is a large boon: more time is spent maintaining and fixing code than writing it, and effort spent on performance is fungible (you can spent it where it matters, instead of wasting time on micro optimizations everywhere).
On the other hand, a value requires that the value be copied into local automatic storage, which has costs.
But if your object is cheap to copy, and you don't want the above effect to occur, always take by value as it makes the compilers job of understanding the function easier.
Naturally only when the value is cheap to copy. If expensive to copy, or even if the copy cost is unknown, that cost should be enough to take by const&.
The short version of the above: taking by value makes it easier for you and the compiler to reason about the state of the parameter.
There is another reason. If your object is cheap to move, and you are going to store a local copy anyhow, taking by value opens up efficiencies. If you take a std::string by const&, then make a local copy, one std::string may be created in order to pass thes parameter, and another created for the local copy.
If you took the std::string by value, only one copy will be created (and possibly moved).
For a concrete example:
std::string some_external_state;
void foo( std::string const& str ) {
some_external_state = str;
}
void bar( std::string str ) {
some_external_state = std::move(str);
}
then we can compare:
int main() {
foo("Hello world!");
bar("Goodbye cruel world.");
}
the call to foo creates a std::string containing "Hello world!". It is then copied again into the some_external_state. 2 copies are made, 1 string discarded.
The call to bar directly creates the std::string parameter. Its state is then moved into some_external_state. 1 copy created, 1 move, 1 (empty) string discarded.
There are also certain exception safety improvements caused by this technique, as any allocation happens outside of bar, while foo could throw a resource exhausted exception.
This only applies when perfect forwarding would be annoying or fail, when moving is known to be cheap, when copying could be expensive, and when you know you are almost certainly going to make a local copy of the parameter.
Finally, there are some small types (like int) which the non-optimized ABI for direct copies is faster than the non-optimized ABI for const& parameters. This mainly matters when coding interfaces that cannot or will not be optimized, and is usually a micro optimization.
I'd like to use the following idiom, that I think is non-standard. I have functions which return vectors taking advantage of Return Value Optimization:
vector<T> some_func()
{
...
return vector<T>( /* something */ );
}
Then, I would like to use
vector<T>& some_reference;
std::swap(some_reference, some_func());
but some_func doesn't return a LValue. The above code makes sense, and I found this idiom very useful. However, it is non-standard. VC8 only emits a warning at the highest warning level, but I suspect other compilers may reject it.
My question is: Is there some way to achieve the very same thing I want to do (ie. construct a vector, assign to another, and destroy the old one) which is compliant (and does not use the assignment operator, see below) ?
For classes I write, I usually implement assignment as
class T
{
T(T const&);
void swap(T&);
T& operator=(T x) { this->swap(x); return *this; }
};
which takes advantage of copy elision, and solves my problem. For standard types however, I really would like to use swap since I don't want an useless copy of the temporary.
And since I must use VC8 and produce standard C++, I don't want to hear about C++0x and its rvalue references.
EDIT: Finally, I came up with
typedef <typename T>
void assign(T &x, T y)
{
std::swap(x, y);
}
when I use lvalues, since the compiler is free to optimize the call to the copy constructor if y is temporary, and go with std::swap when I have lvalues. All the classes I use are "required" to implement a non-stupid version of std::swap.
Since std::vector is a class type and member functions can be called on rvalues:
some_func().swap(some_reference);
If you don't want useless copies of temporaries, don't return by value.
Use (shared) pointers, pass function arguments by reference to be filled in, insert iterators, ....
Is there a specific reason why you want to return by value?
The only way I know - within the constraints of the standard - to achieve what you want are to apply the expression templates metaprogramming technique: http://en.wikipedia.org/wiki/Expression_templates Which might or not be easy in your case.