In this benchmark i cast items as ubyte[] to prevent autodecoding. Still 2.5X slower than a naive equivalent that uses cascaded `replace`.
```
#!dmd -O -release -inline -boundscheck=off
module runnable;
import std.stdio, std.algorithm,std.array, std.conv;
string v1(string message)
{
auto s = "{filepath}({line}:{column})[{type}]: {message}";
const string fileName = "/home/folder/folter/source.d";
const int line = 42;
const int column = 13;
s = s.replace("{filepath}", fileName);
s = s.replace("{line}", to!string(line));
s = s.replace("{column}", to!string(column));
s = s.replace("{type}", "warn");
s = s.replace("{message}", message);
return s;
}
string v3(string message)
{
auto s = "{filepath}({line}:{column})[{type}]: {message}";
const string fileName = "/home/folder/folter/source.d";
const int line = 42;
const int column = 13;
const string isError = "warn";
return cast(string) substitute(cast(ubyte[])s,
cast(ubyte[])"{filepath}", cast(ubyte[])fileName,
cast(ubyte[])"{line}", cast(ubyte[])to!string(column),
cast(ubyte[])"{column}", cast(ubyte[])to!string(column),
cast(ubyte[])"{type}", cast(ubyte[])isError,
cast(ubyte[])"{message}", cast(ubyte[])message
).array;
}
void main()
{
import std.datetime.stopwatch;
benchmark!((){v1("frst version");})(1_000_000).writeln;
benchmark!((){v3("thrd version");})(1_000_000).writeln;
}
```
gives:
[1 sec, 669 ms, 590 μs, and 8 hnsecs]
[3 secs, 5 ms, 266 μs, and 2 hnsecs]
which does not encourage to write idiomatic D code.
Comment #1 by john.loughran.colvin — 2018-03-24T17:03:58Z
Created attachment 1684
benchmark
Comment #2 by john.loughran.colvin — 2018-03-24T17:04:28Z
If you compile with LDC and full optimisations (substitute isn't in LDC's phobos, see attached file for a working example) then the disparity goes away (without bounds checking v3 is even faster). This is normal for range-based code, dmd isn't good at optimising it.
Except that's not the end of the story. If you append extra nonsense to the end of the input string (-version=LongerString in the attached file)then the substitute version gets a lot slower again, so perhaps substitute really is doing something slow and stupid.
Comment #3 by robert.schadek — 2024-12-01T16:33:06Z