SetString() will indeed always create a new allocation buffer, whereas SetLength() will reuse an existing one.
It means that SetString() will never move data, whereas SetLength() could, if the string was already containing something.
Most of the time, we will overwrite the string content, so move() the data is just a time waste.

In case of a function returning a string, the "result" variable is in fact passed by reference (i.e. as implicit var parameter): that is, the previous content is available.
Therefore, SetLength() of a huge result could unnecessarily move a lot of data.

That's why in the mORMot code, we try:

  • either set the string to '' before calling SetLength():
  • either use SetString() with an existing buffer or with nil, which will in fact set to '' then call SetLength().

Of course, this may not be a big deal, but if you are processing a lot of string, especially in the low-level SynCommons.pas unit, it can make a difference.
For instance, in the latest code change of this unit, to include optimized UTF-8/Ansi/Unicode conversions classes, I've used this technique.

We can continue the discussion on our forum.