Whats the best way to send QStrings in a function call? - string

I would like to know what is the most efficient and practical way of sending a Qstring as a parameter to a function, in QT more specifically. I want to use a reference. The problem is I also want to instantiate that string in the function itself like so for example:
this is the function prototype:
void myFunction(QString & theMsg);
this is the function call:
myFunction(tr("Hello StringWorld"));
now the function tr() returns a QString but it doesn't work with a reference(I can see why).
I have to do this:
QString theQstr("Hello StringWorld");
myFunction(theQstr);
Is there a simpler way to do this while still using references or could I just change the function parameter to use a QString and it would still be efficient?

QString uses COW (Copy On Write) behind the scenes, so the actual string isn't copied even if you use a signature like this:
void myFunction(QString theMsg)
(until you modify it that is).
If you absolutely want a reference I would use a const& unless you plan to modify the input argument.
void myFunction(QString const& theMsg)

The most efficient and practical way is using a const reference. The QString COW will be slower than pass by reference but faster than a regular copy.

When you pass a QString, the call site has to call QString copy ctor then a dtor: both implies an atomic reference counting operation (not neglectable), and some more generated assembly code. Hence slower and bigger code (I don't mention here the less common std::move scenario).
On the other hand, when you pass a const QString&, on the called site, there is a double indirection to access the characters: a pointer to a pointer. Hence this is slower than passing a QString, especially if the QString parameter is much used.
I would recommend to always pass a const QString&, and if you need maximum speed on the called side, make a QString copy there, and access this local copy to avoid a double-indirection (faster, less generated code).

Related

Are objects accessed indirectly in D?

As I've read all objects in D are fully location independent. How this requirement is achieved?
One thing that comes to my mind, is that all references are not pointers to the objects, but to some proxy, so when you move object (in memory) you just update that proxy, not all references used in program.
But this is just my guess. How it is done in D for real?
edit: bottom line up front, no proxy object, objects are referenced directly through regular pointers. /edit
structs aren't allowed to keep a pointer to themselves, so if they get copied, they should continue to just work. This isn't strictly enforced by the language though:
struct S {
S* lol;
void beBad() {
lol = &this; // this compiler will allow this....
}
}
S pain() {
S s;
s.beBad();
return s;
}
void main() {
S s;
s = pain();
assert(s.lol !is &s); // but it will also move the object without notice!
}
(EDIT: actually, I guess you could use a postblit to update internal pointers, so it isn't quite without notice. If you're careful enough, you could make it work, but then again, if you're careful enough, you can shoot between your toes without hitting your foot too. EDIT2: Actually no, the compiler/runtime is still allowed to move it without even calling the postblit. One example of where this happens is if it copies a stack frame to the heap to make a closure. The struct data is moved to a new address without being informed. So yeah. /edit)
And actually, that assert isn't guaranteed to pass, the compiler might choose to call pain straight on the local object declared in main, so the pointer would work (though I'm not able to force this optimization here for a demo, generally, when you return a struct from a function, it is actually done via a hidden pointer the caller passes - the caller says "put the return value right here" thus avoiding a copy/move in some cases).
But anyway, the point just is that the compiler is free to copy or not to copy a struct at its leisure, so if you do keep the address of this around in it, it may become invalid without notice; keeping that pointer is not a compile error, but it is undefined behavior.
The situation is different with classes. Classes are allowed to keep references to this internally since a class is (in theory, realized by the garbage collector implementation)) an independent object with an infinite lifetime. While it may be moved (such as be a moving GC (not implemented in D today)), if it is moved, all references to it, internal and external, would also be required to be updated.
So classes can't have the memory pulled out from under them like structs can (unless you the programmer take matters into your own hands and bypass the GC...)
The location independent thing I'm pretty sure is referring only to structs and only to the rule that they can't have pointers to themselves. There's no magic done with references or pointers - they indeed work with memory addresses, no proxy objects.

Assign string to zmq::message_t without copying

I need to do some high performance c++ stuff and that is why I need to avoid copying data whenever possible.
Therefore I want to directly assign a string buffer to a zmq::message_t object without copying it. But there seems to be some deallocation of the string which avoids successful sending.
Here is the piece of code:
for (pair<int, string> msg : l) {
comm_out.send_int(msg.first);
comm_out.send_int(t_id);
int size = msg.second.size();
zmq::message_t m((void *) std::move(msg.second).data(), size, NULL, NULL);
comm_out.send_frame_msg(m, false); // some zmq-wrapper class
}
How can I avoid that the string is deallocated before the message is send out? And when is the string deallocated exactly?
Regards
I think that zmq::message_t m((void *) std::move(msg.second).data()... is probably undefined behaviour, but is certainly the cause of your problem. In this instance, std::move isn't doing what I suspect you think it does.
The call to std::move is effectively creating an anonymous temporary of a string, moving the contents of msg.second into it, then passing a pointer to that temporary data into the message_t constructor. The 0MQ code assumes that pointer is valid, but the temporary object is destroyed after the constructor of message_t completes - i.e. before you call send_frame.
Zero-copy is a complicated matter in 0mq (see the 0MQ Guide) for more details, but you have to ensure that the data that hasn't been copied is valid until 0MQ tells you explicitly that it's finished with it.
Using C++ strings in this situation is hard, and requires a lot of thought. Your question about how to "avoid that the string is deallocated..." goes right to the heart of the issue. The only answer to that is "with great care".
In short, are you sure you need zero-copy at all?

HashMap in OpenCL?

Is it possible to create a simple HashMap in OpenCL? E.g. one where all keys have type long and all values type int, and that never has to be modified (i.e. is passed read-only to the kernel).
Construction of the HashMap can take time (is it done once on the CPU and never has to be modified again), but read-access will be frequent, so get(long key, *hashmap H) should be cheap.
Are there any known implementations for this in OpenCL? I failed to find them. In case I'd have to write one from scratch, which HashMap implementation would be most suitable for this use?
I think that a simple hash table implementation using open addressing could fulfill your requirements here:
By its nature it is stored on a single buffer, and thus trivial to transfer to the kernels.
It's then easy to write the getter logic in the kernel, especially when you don't need any synchronization (read-only).
So, pass a buffer of long2 or a buffer of struct { long key; int val; }, when the first item is the key and the second the value, and also pass the buffer size; now write a regular open-address getter.

c++ multi threading - lock one pointer assignment?

I have a method as below
SomeStruct* abc;
void NullABC()
{
abc = NULL;
}
This is just example and not very interesting.
Many thread could call this method at the same time.
Do I need to lock "abc = NULL" line?
I think it is just pointer so it could be done in one shot and there isn't really need for it but just wanted to make sure.
Thanks
It depends on the platform on which you are running. On many platforms, as long as abc is correctly aligned, the write will be atomic.
However, if your platform does not have such a guarantee, you need to synchronize access to the variable, using a lock, an atomic variable, or an interlocked operation.
No you do not need a lock, at least not on x86. A memory barrier is required in may real world situations though, and locking is one way to get this (the other would be an explicit barrier). You may also consider using an interlocked operation, like VisualC's InterlockedExchangePointer if you need access to the original pointer. There are equivalent intrinsics supported by most compilers.
If no other threads are ever using abc for any other purpose, then the code as shown is fine... but of course it's a bit silly to have a pointer that never gets used except to set it to NULL.
If there is some other code somewhere that does something like this, OTOH:
if (abc != NULL)
{
abc->DoSomething();
}
Then in this case both the code that uses the abc pointer (above) and the code that changes it (that you posted) needed to lock a mutex before accessing (abc). Otherwise the code above risks crashing if the value of abc gets set to NULL after the if statement but before the DoSomething() call.
A borderline case would be if the other code does this:
SomeStruct * my_abc = abc;
if (my_abc != NULL)
{
my_abc->DoSomething();
}
That will probably work, because at the time the abc pointer's value is copied over to my_abc, the value of abc is either NULL or it isn't... and my_abc is a local variable, so other thread's won't be able to change it before DoSomething() is called. The above could theoretically break on some platforms where copying of pointers isn't atomic though (in which case my_abc might end up being an invalid pointer, with have of abc's bits and half NULL bits)... but common/PC hardware will copy pointers atomically, so it shouldn't be an issue there. It might be worthwhile to use a Mutex anyway just to for paranoia's sake though.

How to reset/emptying to a std::wstring?

How to reset/emptying to a std::wstring?
It seems that my function is making a delay when using these line:
std::wstring currentUrl; // <--- I declare this as global.
currentUrl = _bstr_t(url->bstrVal);
Any idea how can I resolve this?
How did you measure that delay? The only reliable way is through a profiler, and a profiler would also show you how that time was spent.
That said, assigning to a string often (unless the string can reuse its old buffer or small string optimization kicks in) involves deleting the old buffer and allocating a new buffer. And dynamic memory is slow.
I don't know _bstr_t, but since std::wstring does only have assignment operators to assign from another std::wstring and const wchar_t*, I assume this is the latter. If that is the case, the string doesn't know the size of the string it will get assigned, so if the string is big, it might have to incrementally increase its buffer, which again involves allocation and deallocation plus copying characters, so this might be quite expensive.
You could try to use an assign() member function instead of the assignment operator. I think there's an overload of assign() that takes a const wchar_t* and the size of the string, allowing it to know the exact buffer size before-hand.
However, as always with performance problems, you need to measure using a profiler. Guessing will not get you far.

Resources