# [erlang-questions] string concatenation efficiency

Richard A. O'Keefe <>
Fri Jan 29 02:24:14 CET 2016

```On 28/01/16 8:22 pm, Khitai Pang wrote:
> For string concatenation, which one of the following is the most
> efficient?
>
> 1)
> strings:join(["Item:{", ItemID, "}")], ""]
>
> 2)
> lists:append(["Item:{", ItemID, "}")])
>
> 3)
> "Item:{" ++ ItemID ++ "}"
>
> Here ItemID is a UUID.
For something this size, it hardly matters.

The definition of lists:append/1 is
append([E])     -> E;
append([H|T]) -> H ++ append(T);
append([])      -> [].
so lists:append([A,B,C]) -> A ++ lists:append([B,C])
-> A ++ B ++ lists:append([C])
-> A ++ B ++ C.
Clearly, there is no way for this to be more efficient than
writing A ++ B ++ C directly.

The definition of string:join/2 is
join([], Sep) when is_list(Sep) -> [];
join([H|T], Sep)                      ->    H ++ lists:append([Sep
++ X || X <- T]).
-- at least in 18.1 -- which rather startled me because I was expecting
join([E], Sep) when is_list(Sep) -> E;
join([H|T], Sep) -> H ++ Sep ++ join(T, Sep);
join([], Sep) when is_list(Sep) -> [].
Clearly, there is no way that either version of join/2 can be faster than
append/1.  In fact
append/1 is measurably faster than
the revised join/2, which is measurably faster than
the original join/2,
but you have to push the sizes ridiculously high to make these measurements.

Really, I suggest you write whichever makes your intentions clearest
to human readers, get the program going, then measure it.  I would
be surprised if this particular issue made any significant difference.

But why are you using strings at all?
Strings are an *interface* data type; you process them when you receive
data from an external source and you generate them (or rather you
generate iolists) when you are sending data to an external source, but
for internal processing you usually want some sort of tree.

Seeing "Item:{\$ItemID}" suggests that maybe you *are* generating output
for some external process, but in that case, perhaps you should just be
sending along the iolist ["Item:{",ItemId,"}"] and *not* concatenating the
pieces.

```