PDA

View Full Version : What is best for concatenating values in QString: arg(...) or +?



Momergil
2nd April 2014, 16:50
Hello!

Suppose I want to create a string that shows a progress status bar, something like:

"Processing file 1 of 211 files: 5% done".

I know of two methods one could do that by working with QStrings: one is to pick the numbers and convert them to QStrings by using QString::number(...) and concatenate them using +:



"Processing file " + QString::number(currFile) + " of " + QString::number(totalFiles) + " files: " + QString::number(currProgress) + "% done";


and the other is by using args:



"Processing file %1 of %2 files: %3% done".arg(currFile).arg(totalFiles).arg(currProgress);



So two questions:
* First, is there another method to do this?
* Second, which of them is the best for situations like the one mentioned above? - I know that if someone wants to guarantee a minimal amount of numbers to be displayed, arg() is better since number(...) don't provide that functionality, but what about speed and memory efficiency? - Not forgetting to consider in the evaluation some extra options such as to use QStringBuilder to make the + concatenation faster.


Thanks,

Momergil

stampede
2nd April 2014, 17:52
First, is there another method to do this?
Sure, you can use append() or push_back(), operator +=, or even sprintf, but I really doubt you will notice any change in performance with such micro-optimizations.

Second, which of them is the best for situations like the one mentioned above?
The most readable one (for me the "arg()" method, but it is a matter of personal preference).

what about speed and memory efficiency?
The thing you are doing in the background and stuff related to gui will have much greater impact on the performance than actual string composition.
Anyway, if you are unsure, then measure, do some performance tests.

anda_skoa
2nd April 2014, 18:07
The second option (using arg()) is the only one that works for translations.

Cheers,
_

Momergil
2nd April 2014, 19:03
Sure, you can use append() or push_back(), operator +=, or even sprintf, but I really doubt you will notice any change in performance with such micro-optimizations.

Ok, it seems I knew all the other methods all along then :) Now about performance optimization, well, if one is using a computer with a Intel i7 3.5Ghz or something, I really agree that no one will actually feel any difference, but what about software in embedded system, when processors and memory are far less available? And what about the pride of a programmer in doing not simply "code that works", but "good code that works better", even if just slightly better? ;)


Now anda_skoa, you mentioned something that really caught my attention... How exactly that only arg() works with translations? I mean, if I change the first example code to



tr("Processing file ") + QString::number(currFile) + tr(" of ") + QString::number(totalFiles) + tr(" files: ") + QString::number(currProgress) + tr("% done");


wouldn't translations works anyway (with the only probable unhappiness of having to translated small, incomplete and uncontextualized strings in QtTranslator?) And, in fact, how exactly one would use the QObject::tr() method using the arg() way? (Sorry if the answer is in QtAssistant; I haven't read all Qt's translation API's documents yet :T)

stampede
2nd April 2014, 20:07
wouldn't translations works anyway (with the only probable unhappiness of having to translated small, incomplete and uncontextualized strings in QtTranslator?)
Exactly, maybe slightly more difficult for a translator do to her job.

And, in fact, how exactly one would use the QObject::tr() method using the arg() way?


//: a special kind of comment that will appear in linguist
tr("Somestring %1").arg(something)

One of our coding guidelines is to keep the translatable strings separated from string arguments, special markers, parameters etc, so very often you can see code like


tr("Some string:") + " " + QString::number(value) + "\n" + tr("Another string") + ...;

Personally not my favourite style, but its for the sake of people working on translations. From what I've heard, it makes things simpler for them (together with those special kind of comments to describe context etc.)

what about software in embedded system, when processors and memory are far less available?
I don't have much experience with that, but I think if it can run Qt gui, then it most definitely can run few string concats ;)

And what about the pride of a programmer in doing not simply "code that works", but "good code that works better", even if just slightly better?
For the critical parts of the app, of course. For the rest I'd say "clean code" >> "smart code" :D

wysota
3rd April 2014, 09:35
There is also a third method:


#include <QStringBuilder>

QString string = "abc" % QString::number(currFile) % ... ;

This solution is fastest yet less powerful than when using arg() since the latter is better when using tr() for translations.

anda_skoa
3rd April 2014, 11:29
Now anda_skoa, you mentioned something that really caught my attention... How exactly that only arg() works with translations? I mean, if I change the first example code to



tr("Processing file ") + QString::number(currFile) + tr(" of ") + QString::number(totalFiles) + tr(" files: ") + QString::number(currProgress) + tr("% done");


wouldn't translations works anyway (with the only probable unhappiness of having to translated small, incomplete and uncontextualized strings in QtTranslator?)

That only works for languages with exactly the same order of arguments.
The positional arguments used by QString::arg() allow translators to shft the position of these arguments depending in their target language's needs.



And, in fact, how exactly one would use the QObject::tr() method using the arg() way? (Sorry if the answer is in QtAssistant; I haven't read all Qt's translation API's documents yet :T)



tr("Processing file %1 of %2 files: %3% done").arg(currFile).arg(totalFiles).arg(currProgress);


Cheers,
_

Momergil
3rd April 2014, 13:56
Well, thanks both anda_skoa, wysota and stampede for you replies. They will all give me somethings to think about for the next days :)