Sometimes 100 lines of code can fix your ctfe perf
Ali Çehreli
acehreli at yahoo.com
Tue Aug 24 22:33:14 UTC 2021
On 8/24/21 1:14 PM, Paul Backus wrote:
>> On Tuesday, 24 August 2021 at 16:58:26 UTC, Adam D Ruppe wrote:
>>> On Tuesday, 24 August 2021 at 16:52:30 UTC, Ali Çehreli wrote:
>>>> auto s = format!"hello %s world %s"(a, b);
>>>
>>> yikes that's like the worst thing in the whole D world. brutally slow
>>> by all metrics.
[...]
> Internally, `format` uses `formattedWrite`
> with an `Appender` as the output range [1]
That's what I thought. Additionally, some of my structs define
toString() functions that work with a "sink" so they would be written
into the buffer of an appender without extra string creation:
https://dlang.org/library/std/format/write.html
To do even better, we could write the following function that reuses a
static Appender object:
auto appendingFormatter(string fmt, string file = __FILE__, size_t line
= __LINE__, Args...)(Args args) {
import std.array : Appender;
import std.format : formattedWrite;
static Appender!(char[]) buffer;
buffer.clear();
buffer.formattedWrite!fmt(args);
return buffer.data;
}
import std.stdio;
void main() {
size_t total;
enum N = 100;
foreach (i; 0 .. N) {
foreach (d; 0 .. N) {
total += appendingFormatter!"hello %s world %s"(i, d).length;
total += appendingFormatter!"goodbye %s moon %s"(i * 10, d /
7).length;
}
}
writeln(appendingFormatter!"An arbitrary value: %s"(total));
const a = appendingFormatter!"%s"(42); const b =
appendingFormatter!"%s"(43);
// BUG: Fails.
assert((a == "42") && (b == "43"));
}
Performance is awesome because there is almost no memory allocation.
Unfortunately, there is that bug on the last line of main because there
is no __COLUMN__ or __ID__ or __COUNTER__ or etc. that would differ per
__LINE__. Or, is there? Please? :)
Do you know a trick that would pass that assertion?
Ali
More information about the Digitalmars-d
mailing list