This post is related to this one

Let us see extremely simple test

StringTemplate["1``3"][2] // RepeatedTiming
"1" <> ToString[2] <> "3" // RepeatedTiming


{0.000120292, "123"}
{1.0749*10^-6, "123"}

Then, I looked into the Trace of StringTemplate. It give out pages of complex trace result.

StringTemplate["1``3"][2] // Trace


There are tons of more!

At first, I though I know why StringTemplate takes so long. But then I tried to write a faster one myself. Currently, I only got this

stringTemplate[string_][x__] := Module[{},
  xList = TextString /@ {x};
  split = StringSplit[string, "``" -> "``"];
  pos = Flatten@Position[split, "``"];
   split[[pos[[i]]]] = xList[[i]], {i, 1, Length@xList}];

Which only support unnumbered "``", and it is not that fast either

stringTemplate["1``3"][2] // RepeatedTiming
{0.00001226, "123"}

I found it is hard for me to write a stringtemplate support numbered or named slot. So is it possible to write a more efficient StringTemplate then built-in?

  • 2
    $\begingroup$ This reads as a complaint, thinly disguised as a question. I am not sure what answer this community could provide. It is a bit unfair to compare a use case like the first one, in which StringTemplate is obviously far too complex a tool for the job. The old post you linked had a better example of the trade-off between the readability and ease of use of StringTemplate, and the speed of a series of manually-coded StringJoin + conversions. For everyday code that is not time-sensitive, I tend to choose readability (= maintainability) over performance if the penalty is bearable. $\endgroup$
    – MarcoB
    Jul 5 at 15:43
  • 1
    $\begingroup$ @MarcoB Thank you for reply. I must confess I had a complain. Actually, for me, even a simple case like that in the post, I would choose to StringTemplate, because it is much more readable, and not error prone. But were you not surprised by the trace of StringTemplate? I made this post to get a reasonable explanation that StringTemplate really needs to be that complex. If not, then StringTemplate apparently needs to be fixed as I naively think. $\endgroup$
    – matheorem
    Jul 5 at 15:54
  • 7
    $\begingroup$ Have you tried ToString @ StringForm[...]? $\endgroup$ Jul 5 at 18:09
  • $\begingroup$ @SjoerdSmit Thank you so much! StringForm is much faster, I did not notice this before. $\endgroup$
    – matheorem
    Jul 6 at 1:49
  • 3
    $\begingroup$ StringForm is an old function that fills the need of printf. It's very useful for displaying messages, but just be aware that it doesn't actually produce strings; just something that looks like a string in the FrontEnd. So if you need an actual string, ToString @ StringForm[...] usually works. $\endgroup$ Jul 6 at 7:27

2 Answers 2


Here's an attempt:

MyStringTemplate[form_String][repls__] :=
    {positions = StringPosition[form, "``"],
     stringRepls = ToString /@ {repls}},
    StringReplacePart[form, PadRight[stringRepls, Length@positions, ""], positions]]

But I'm not really sure this qualifies as an answer. Or rather, I'm not sure the question was well formed. As the original post points out, StringTemplate is just a special constructor for a TemplateObject. The whole domain of templating functionality in Mathematica goes way beyond strings. So I think that it's a bit misguided to criticize StringTemplate as if it were a simple analogue of printf.

  • $\begingroup$ "I'm not sure the question was well formed" - it wasn't. $\endgroup$
    – Jason B.
    Jul 5 at 17:51
  • $\begingroup$ Great use of StringReplacePart, Thank you so much! $\endgroup$
    – matheorem
    Jul 6 at 3:47
  • $\begingroup$ Well, I feel a bit silly after seeing the comment about StringForm. $\endgroup$
    – lericr
    Jul 6 at 4:48
  • $\begingroup$ This does not work with associations. MyStringTemplate["a"]@<|"a" -> 1|> $\endgroup$
    – Kuba
    Jul 6 at 5:16

The most closest to StringTemplate that I write at the moment


it supports unnumbered, numbered, named slots.

myST["1``3"][2] // RepeatedTiming
StringTemplate["1``3"][2] // RepeatedTiming

myST["1`a`3"][<|"a" -> 2|>] // RepeatedTiming
StringTemplate["1`a`3"][<|"a" -> 2|>] // RepeatedTiming


{7.63838*10^-6, "123"}
{0.000121687, "123"}
{0.0000115606, "123"}
{0.000130099, "123"}

Not the answer you're looking for? Browse other questions tagged or ask your own question.