newCTFE gets a 10x faster string concat

Stefan Koch uplink.coder at googlemail.com
Thu Sep 23 13:01:33 UTC 2021


Hi there,

in preparation for my little talk/demo of newCTFE I have worked 
on a few things to make it less embarrassing.
Consider the following code:
```d
string makeBigString(int N)
{
     string x = "this is the string I want to append\n";
     string result = "";
     foreach(_; 0 .. N)
     {
         result ~= x;
     }
     return result;
}

pragma(msg, makeBigString(short.max / 4).length);
```

An hour ago this would had this embarrassing outcome:
```
Benchmark #1: generated/linux/release/64/dmd -c 
testStringConcat.d  -new-ctfe
   Time (mean ± σ):     831.7 ms ±  29.3 ms    [User: 320.9 ms, 
System: 509.5 ms]
   Range (min … max):   805.9 ms … 880.9 ms    10 runs

Benchmark #2: generated/linux/release/64/dmd -c testStringConcat.d
   Time (mean ± σ):     378.2 ms ±  12.1 ms    [User: 102.6 ms, 
System: 274.9 ms]
   Range (min … max):   366.7 ms … 400.0 ms    10 runs

Summary
   'generated/linux/release/64/dmd -c testStringConcat.d' ran
     2.20 ± 0.10 times faster than 'generated/linux/release/64/dmd 
-c testStringConcat.d  -new-ctfe'
```

With new CTFE being twice as slow.
And if you had written
```d
pragma(msg, makeBigString(short.max).length);
```
you would have gotten something even more embarrassing:

`core.exception.AssertError at src/dmd/ctfe/bc.d(3675): !!! HEAP 
OVERFLOW !!!`

I have fixed that now.
As of a few moments ago the results look different though.

for
```d
pragma(msg, makeBigString(short.max/4).length);
```

you now get:
```
Benchmark #1: generated/linux/release/64/dmd -c 
testStringConcat.d  -new-ctfe
   Time (mean ± σ):      55.3 ms ±   2.7 ms    [User: 40.4 ms, 
System: 14.7 ms]
   Range (min … max):    48.2 ms …  63.8 ms    50 runs

Benchmark #2: generated/linux/release/64/dmd -c testStringConcat.d
   Time (mean ± σ):     387.6 ms ±  16.6 ms    [User: 112.0 ms, 
System: 274.6 ms]
   Range (min … max):   372.5 ms … 420.9 ms    10 runs

Summary
   'generated/linux/release/64/dmd -c testStringConcat.d  
-new-ctfe' ran
     7.01 ± 0.45 times faster than 'generated/linux/release/64/dmd 
-c testStringConcat.d'
```

and for  for `pragma(msg, makeBigString(short.max).length);`

```
Benchmark #1: generated/linux/release/64/dmd -c 
testStringConcat.d  -new-ctfe
   Time (mean ± σ):     498.6 ms ±  16.0 ms    [User: 209.3 ms, 
System: 287.7 ms]
   Range (min … max):   481.8 ms … 523.6 ms    10 runs

Benchmark #2: generated/linux/release/64/dmd -c testStringConcat.d
   Time (mean ± σ):      5.094 s ±  0.130 s    [User: 995.8 ms, 
System: 4086.8 ms]
   Range (min … max):    4.909 s …  5.270 s    10 runs

Summary
   'generated/linux/release/64/dmd -c testStringConcat.d  
-new-ctfe' ran
    10.22 ± 0.42 times faster than 'generated/linux/release/64/dmd 
-c testStringConcat.d'
```

Which is the 10x faster that I was talking about.

If you want to know how I was able to speed it up attend my 
demonstration at beerconf on Saturday.

P.S.
In terms of memory use we are looking at  `1.3 GB` for `newCTFE` 
and
`18.1GB` for "oldCTFE".

which is roughly a 13x difference.

Cheers,
Stefan


More information about the Digitalmars-d mailing list