dmd -run speed trends
Witold Baryluk
witold.baryluk at gmail.com
Thu Dec 7 16:32:32 UTC 2023
I do not use `dmd -run` too often, but recently was checking out
Nim language, and they also do have run option, plus pretty fast
compiler, so checked it out.
Then, I was curious about trends of `dmd -run`, and did some
historical tracking.
The example is simple example from nim website, ported to Python
and D. It imports `writefln`, and `std.array` (for split),
defines a simple data only class, construct array of few objects,
do some iterations, as well do some very small compile time
generation, and generator (in I used foreach over delegate). It
is very small program, with nothing interesting going on, so we
are are mostly measuring compiler, linker, parsing few libraries
we import, and startup times.
| x | min wall time [ms] | Notes |
| --- | ---: | --- |
| Python 3.11.6 | 31.4 |
| Nim 2.0.0 (cached) | 139.4 |
| Nim 2.0.0 (uncached) | 711.4 | cached binary removed before
each re-run |
| gdc 13.2.0-7 | 1117.0 |
| dmd 2.106.0 | 728.1 |
| dmd 2.105.3 | 712.9 |
| dmd 2.104.2 | 728.2 |
| dmd 2.103.1 | 714.7 |
| dmd 2.102.2 | 714.0 |
| dmd 2.101.2 | 853.0 |
| dmd 2.100.2 | 842.9 |
| dmd 2.099.1 | 843.7 |
| dmd 2.098.1 | 898.1 |
| dmd 2.097.2 | 771.9 |
| dmd 2.096.1 | 729.7 |
| dmd 2.095.1 | 723.1 |
| dmd 2.094.2 | 1008 |
| dmd 2.093.1 | 1078 |
| dmd 2.092.1 | 1073 |
| dmd 2.091.1 | 790.6 |
| dmd 2.090.1 | 794.0 |
| dmd 2.089.1 | 771.1 |
| dmd 2.088.1 | 802.1 |
| dmd 2.087.1 | 790.6 |
| dmd 2.086.1 | 769.4 |
| dmd 2.085.1 | 822.6 |
| dmd 2.084.1 | 771.3 |
| dmd 2.083.1 | 784.0 |
| dmd 2.082.1 | 765.4 |
| dmd 2.081.2 | 693.0 |
| dmd 2.080.1 | 685.5 |
| dmd 2.079.1 | 650.4 |
| dmd 2.078.3 | 628.2 |
| dmd 2.077.1 | 626.3 |
| dmd 2.076.1 | 618.8 |
| dmd 2.075.1 | 589.9 |
| dmd 2.074.1 | 564.3 |
| dmd 2.073.2 | 574.3 |
| dmd 2.072.2 | 590.4 |
| dmd 2.071.2 | n/a | Linker issues |
| dmd 2.070.2 | n/a | Linker issues |
| dmd 2.069.2 | n/a | Linker issues |
| dmd 2.065.0 | n/a | Linker issues |
| dmd 2.064.0 | n/a | No std.array.split available |
Measurement error is <0.1%. (idle Linux system, performance
governor, 240 or more repetitions, minimums taken).
So, not too bad, but not too good either.
We are not regressing too much, but things could be improved:
Sizes of imports reduced, Compiler in general speed up, and for
-run, some intermediate form cached on disk to speed up parsing,
for various imports, or for the final binary.
Environment: Debian Linux amd64, Threadripper 2950X, all inputs
and outputs in RAM on tmpfs (including compilers and libraries).
GNU ld (GNU Binutils for Debian) 2.41.50.20231202
Reference code:
```d
#!/usr/bin/env -S dmd -run
struct Person {
string name;
int age;
}
auto people = [
Person("John", 45),
Person("Kate", 30),
];
void main() {
import std.stdio : writefln;
foreach (person; people) {
writefln("%s is %d years old", person.name, person.age);
}
static auto oddNumbers(T)(T[] a) {
return delegate int(int delegate(ref T) dg) {
foreach (x; a) {
if (x % 2 == 0) continue;
auto ret = dg(x);
if (ret != 0) return ret;
}
return 0;
};
}
foreach (odd; oddNumbers([3, 6, 9, 12, 15, 18])) {
writefln("%d", odd);
}
static auto toLookupTable(string data) {
import std.array : split;
bool[string] result;
foreach (w; data.split(';')) {
result[w] = true;
}
return result;
}
enum data = "mov;btc;cli;xor;afoo";
enum opcodes = toLookupTable(data);
foreach (o, k; opcodes) {
writefln("%s", o);
}
}
```
```python
#!/usr/bin/env python3
import dataclasses
@dataclasses.dataclass
class Person:
name: str
age: int
people = [
Person(name="John", age=45),
Person(name="Kate", age=30),
]
for person in people:
print(f"{person.name} is {person.age} years old")
def oddNumbers(a):
for x in a:
if x % 2 == 1:
yield x
for odd in oddNumbers([3, 6, 9, 12, 15, 18]):
print(odd)
def toLookupTable(data):
result = set()
for w in data.split(";"):
result.add(w)
return result
data = "mov;btc;cli;xor;afoo"
opcodes = toLookupTable(data)
for o in opcodes:
print(o)
```
```nim
#!/usr/bin/env -S /home/user/nim-2.0.0/bin/nim r --warnings:off
--hints:off
import std/strformat
type Person = object
name: string
age: Natural # Ensures the age is positive
let people = [
Person(name: "John", age: 45),
Person(name: "Kate", age: 30),
]
for person in people:
echo(fmt"{person.name} is {person.age} years old")
iterator oddNumbers[Idx, T](a: array[Idx, T]): T =
for x in a:
if x mod 2 == 1:
yield x
for odd in oddNumbers([3, 6, 9, 12, 15, 18]):
echo odd
import macros, strutils
macro toLookupTable(data: static[string]): untyped =
result = newTree(nnkBracket)
for w in data.split(';'):
result.add newLit(w)
const
data = "mov;btc;cli;xor;afoo"
opcodes = toLookupTable(data)
for o in opcodes:
echo o
```
More information about the Digitalmars-d
mailing list