Skip to content

Commit 276e8f8

Browse files
committed
Decrease compile time
std.format and std.numeric.gcd shows up quite heavily during tracing compile times. This PR removes two expansive format calls and introduces a super simple gcd algorithm.
1 parent 46ac54e commit 276e8f8

File tree

2 files changed

+50
-41
lines changed

2 files changed

+50
-41
lines changed

source/taggedalgebraic/taggedalgebraic.d

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ unittest {
110110
struct TaggedAlgebraic(U) if (is(U == union) || is(U == struct) || is(U == enum))
111111
{
112112
import std.algorithm : among;
113-
import std.string : format;
113+
import std.conv : to;
114114

115115
/// Alias of the type used for defining the possible storage types/kinds.
116116
deprecated alias Union = U;
@@ -1313,58 +1313,60 @@ private enum OpKind {
13131313

13141314
deprecated alias TypeEnum(U) = UnionFieldEnum!U;
13151315

1316+
private string generateConstructor1(string tname) {
1317+
return "this(UnionType.FieldTypeByName!\"" ~ tname ~ `" value)
1318+
{
1319+
static if (isUnitType!(UnionType.FieldTypeByName!"` ~ tname ~ `"))
1320+
m_union.set!(Kind.` ~ tname ~ `)();
1321+
else
1322+
m_union.set!(Kind.` ~ tname ~ `)(value);
1323+
}
1324+
1325+
void opAssign(UnionType.FieldTypeByName!"` ~ tname ~ `" value)
1326+
{
1327+
static if (isUnitType!(UnionType.FieldTypeByName!"` ~ tname ~ `"))
1328+
m_union.set!(Kind.` ~ tname ~ `)();
1329+
else
1330+
m_union.set!(Kind.` ~ tname ~ `)(value);
1331+
}`;
1332+
}
1333+
1334+
private string generateConstructor2(string tname) {
1335+
return `this(UnionType.FieldTypeByName!"` ~ tname ~ `" value, Kind type)
1336+
{
1337+
switch (type) {
1338+
foreach (i, n; TaggedUnion!U.fieldNames) {
1339+
static if (is(UnionType.FieldTypeByName!"` ~ tname ~ `" == UnionType.FieldTypes[i])) {
1340+
case __traits(getMember, Kind, n):
1341+
static if (isUnitType!(UnionType.FieldTypes[i]))
1342+
m_union.set!(__traits(getMember, Kind, n))();
1343+
else m_union.set!(__traits(getMember, Kind, n))(value);
1344+
return;
1345+
}
1346+
}
1347+
// NOTE: the default case needs to be at the bottom to avoid bogus
1348+
// unreachable code warnings (DMD issue 21671)
1349+
default: assert(false, "Invalid type ID for type " ~
1350+
UnionType.FieldTypeByName!"` ~ tname ~ `".stringof ~ ": " ~ to!(string)(type));
1351+
}
1352+
}`;
1353+
}
13161354

13171355
private string generateConstructors(U)()
13181356
{
13191357
import std.algorithm : map;
13201358
import std.array : join;
1321-
import std.string : format;
13221359
import std.traits : FieldTypeTuple;
13231360

13241361
string ret;
13251362

1326-
13271363
// normal type constructors
13281364
foreach (tname; UniqueTypeFields!U)
1329-
ret ~= q{
1330-
this(UnionType.FieldTypeByName!"%1$s" value)
1331-
{
1332-
static if (isUnitType!(UnionType.FieldTypeByName!"%1$s"))
1333-
m_union.set!(Kind.%1$s)();
1334-
else
1335-
m_union.set!(Kind.%1$s)(value);
1336-
}
1337-
1338-
void opAssign(UnionType.FieldTypeByName!"%1$s" value)
1339-
{
1340-
static if (isUnitType!(UnionType.FieldTypeByName!"%1$s"))
1341-
m_union.set!(Kind.%1$s)();
1342-
else
1343-
m_union.set!(Kind.%1$s)(value);
1344-
}
1345-
}.format(tname);
1365+
ret ~= generateConstructor1(tname);
13461366

13471367
// type constructors with explicit type tag
13481368
foreach (tname; AliasSeq!(UniqueTypeFields!U, AmbiguousTypeFields!U))
1349-
ret ~= q{
1350-
this(UnionType.FieldTypeByName!"%1$s" value, Kind type)
1351-
{
1352-
switch (type) {
1353-
foreach (i, n; TaggedUnion!U.fieldNames) {
1354-
static if (is(UnionType.FieldTypeByName!"%1$s" == UnionType.FieldTypes[i])) {
1355-
case __traits(getMember, Kind, n):
1356-
static if (isUnitType!(UnionType.FieldTypes[i]))
1357-
m_union.set!(__traits(getMember, Kind, n))();
1358-
else m_union.set!(__traits(getMember, Kind, n))(value);
1359-
return;
1360-
}
1361-
}
1362-
// NOTE: the default case needs to be at the bottom to avoid bogus
1363-
// unreachable code warnings (DMD issue 21671)
1364-
default: assert(false, format("Invalid type ID for type %%s: %%s", UnionType.FieldTypeByName!"%1$s".stringof, type));
1365-
}
1366-
}
1367-
}.format(tname);
1369+
ret ~= generateConstructor2(tname);
13681370

13691371
return ret;
13701372
}

source/taggedalgebraic/taggedunion.d

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,11 +752,18 @@ package template AmbiguousTypes(Types...) {
752752
alias AmbiguousTypes = impl!0;
753753
}
754754

755+
private size_t gcd(size_t a, size_t b) {
756+
while (b != 0) {
757+
size_t temp = b;
758+
b = a % b;
759+
a = temp;
760+
}
761+
return a;
762+
}
763+
755764
/// Computes the minimum alignment necessary to align all types correctly
756765
private size_t commonAlignment(TYPES...)()
757766
{
758-
import std.numeric : gcd;
759-
760767
size_t ret = 1;
761768
foreach (T; TYPES)
762769
ret = (T.alignof * ret) / gcd(T.alignof, ret);

0 commit comments

Comments
 (0)