Last active
November 22, 2020 12:50
-
-
Save UplinkCoder/d29dd143b352d28390426a3ffedf9521 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# compiler commit hash: 0e837363832a5deb0447e10f9e615c0497e521f7 | |
# which got compiled with the following commandline: | |
# make -f posix.mak HOST_DMD=~/d/ldc2-1.23.0-linux-x86_64/bin/ldmd2 DFLAGS+="-g -O3" | |
uplimk@uplimk-virtual-machine:~/d/dmd$ hyperfine -w 10 "generated/linux/release/64/dmd xx_tf.d -sktf -c" "generated/linux/release/64/dmd xx.d -c " "generated/linux/release/64/dmd xx_adam.d -c" | |
Benchmark #1: generated/linux/release/64/dmd xx_tf.d -sktf -c | |
Time (mean ± σ): 9.1 ms ± 0.4 ms [User: 5.8 ms, System: 3.2 ms] | |
Range (min … max): 8.5 ms … 10.7 ms 288 runs | |
0.02user 0.01system 0:00.04elapsed 92%CPU (0avgtext+0avgdata 11672maxresident)k | |
0inputs+8outputs (0major+1769minor)pagefaults 0swaps | |
tuple((uint), (dchar), (int), (ulong), (long)) | |
0.02user 0.01system 0:00.04elapsed 97%CPU (0avgtext+0avgdata 11556maxresident)k | |
0inputs+0outputs (0major+1768minor)pagefaults 0swaps | |
tuple((uint), (dchar), (int), (ulong), (long)) | |
0.02user 0.01system 0:00.03elapsed 94%CPU (0avgtext+0avgdata 11660maxresident)k | |
Benchmark #2: generated/linux/release/64/dmd xx.d -c | |
Time (mean ± σ): 17.3 ms ± 0.6 ms [User: 11.3 ms, System: 5.9 ms] | |
Range (min … max): 16.5 ms … 19.5 ms 166 runs | |
0.05user 0.01system 0:00.07elapsed 97%CPU (0avgtext+0avgdata 24960maxresident)k | |
0inputs+8outputs (0major+5120minor)pagefaults 0swaps | |
(int, uint, long, ulong, float, double, real, dchar) | |
0.03user 0.01system 0:00.05elapsed 88%CPU (0avgtext+0avgdata 24936maxresident)k | |
0inputs+0outputs (0major+5120minor)pagefaults 0swaps | |
(int, uint, long, ulong, float, double, real, dchar) | |
0.05user 0.00system 0:00.06elapsed 98%CPU (0avgtext+0avgdata 24940maxresident)k | |
0inputs+0outputs (0major+5119minor)pagefaults 0swaps | |
Benchmark #3: generated/linux/release/64/dmd xx_adam.d -c | |
Time (mean ± σ): 20.4 ms ± 0.7 ms [User: 15.2 ms, System: 5.0 ms] | |
Range (min … max): 19.5 ms … 22.7 ms 144 runs | |
0.05user 0.00system 0:00.06elapsed 95%CPU (0avgtext+0avgdata 19476maxresident)k | |
0inputs+8outputs (0major+3745minor)pagefaults 0swaps | |
(ushort, wchar, short, uint, dchar, int, ulong, long) | |
0.03user 0.02system 0:00.05elapsed 91%CPU (0avgtext+0avgdata 19564maxresident)k | |
0inputs+0outputs (0major+3749minor)pagefaults 0swaps | |
(ushort, wchar, short, uint, dchar, int, ulong, long) | |
0.04user 0.01system 0:00.06elapsed 92%CPU (0avgtext+0avgdata 19552maxresident)k | |
0inputs+0outputs (0major+3745minor)pagefaults 0swaps | |
Summary | |
'generated/linux/release/64/dmd xx_tf.d -sktf -c' ran | |
1.91 ± 0.11 times faster than 'generated/linux/release/64/dmd xx.d -c ' | |
2.24 ± 0.13 times faster than 'generated/linux/release/64/dmd xx_adam.d -c' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template ApplyLeft(alias Template, args...) | |
{ | |
alias ApplyLeft(right...) = SmartAlias!(Template!(args, right)); | |
} | |
private template SmartAlias(T...) | |
{ | |
static if (T.length == 1) | |
{ | |
alias SmartAlias = Alias!T; | |
} | |
else | |
{ | |
alias SmartAlias = T; | |
} | |
} | |
alias Alias(alias a) = a; | |
alias Alias(T) = T; | |
template Filter(alias pred, TList...) | |
{ | |
static if (TList.length < filterExpandFactor) | |
{ | |
mixin(FilterShortCode[TList.length]); | |
} | |
else | |
{ | |
template MaybeNothing(Q...) | |
{ | |
static if (pred!(Q[0])) | |
alias MaybeNothing = AliasSeq!(Q[0]); | |
else | |
alias MaybeNothing = Nothing; | |
} | |
alias Filter = staticMap!(MaybeNothing, TList); | |
} | |
} | |
private enum staticMapExpandFactor = 150; | |
private string generateCases() | |
{ | |
string[staticMapExpandFactor] chunks; | |
chunks[0] = q{}; | |
static foreach (enum i; 0 .. staticMapExpandFactor - 1) | |
chunks[i + 1] = chunks[i] ~ `F!(Args[` ~ i.stringof ~ `]),`; | |
string ret = `AliasSeq!(`; | |
foreach (chunk; chunks) | |
ret ~= `q{alias staticMap = AliasSeq!(` ~ chunk ~ `);},`; | |
return ret ~ `)`; | |
} | |
private alias staticMapBasicCases = AliasSeq!(mixin(generateCases())); | |
/** | |
Evaluates to $(D AliasSeq!(F!(T[0]), F!(T[1]), ..., F!(T[$ - 1]))). | |
*/ | |
template staticMap(alias F, Args...) | |
{ | |
static if (Args.length < staticMapExpandFactor) | |
mixin(staticMapBasicCases[Args.length]); | |
else | |
alias staticMap = AliasSeq!(staticMap!(F, Args[0 .. $ / 2]), | |
staticMap!(F, Args[$ / 2 .. $])); | |
} | |
alias AliasSeq(TList...) = TList; | |
private alias FilterShortCode = AliasSeq!(q{ | |
alias Filter = Nothing; | |
}, q{ | |
static if (pred!(TList[0])) | |
alias Filter = AliasSeq!(TList[0]); | |
else | |
alias Filter = Nothing; | |
}, q{ | |
static if (pred!(TList[0])) | |
{ | |
static if (pred!(TList[1])) | |
alias Filter = AliasSeq!(TList[0], TList[1]); | |
else | |
alias Filter = AliasSeq!(TList[0]); | |
} | |
else | |
{ | |
static if (pred!(TList[1])) | |
alias Filter = AliasSeq!(TList[1]); | |
else | |
alias Filter = Nothing; | |
} | |
}, q{ | |
static if (pred!(TList[0])) | |
{ | |
static if (pred!(TList[1])) | |
{ | |
static if (pred!(TList[2])) | |
alias Filter = AliasSeq!(TList[0], TList[1], TList[2]); | |
else | |
alias Filter = AliasSeq!(TList[0], TList[1]); | |
} | |
else | |
{ | |
static if (pred!(TList[2])) | |
alias Filter = AliasSeq!(TList[0], TList[2]); | |
else | |
alias Filter = AliasSeq!(TList[0]); | |
} | |
} | |
else | |
{ | |
static if (pred!(TList[1])) | |
{ | |
static if (pred!(TList[2])) | |
alias Filter = AliasSeq!(TList[1], TList[2]); | |
else | |
alias Filter = AliasSeq!(TList[1]); | |
} | |
else | |
{ | |
static if (pred!(TList[2])) | |
alias Filter = AliasSeq!(TList[2]); | |
else | |
alias Filter = Nothing; | |
} | |
} | |
}, q{ | |
static if (pred!(TList[0])) | |
{ | |
static if (pred!(TList[1])) | |
{ | |
static if (pred!(TList[2])) | |
{ | |
static if (pred!(TList[3])) | |
alias Filter = AliasSeq!(TList[0], TList[1], TList[2], TList[3]); | |
else | |
alias Filter = AliasSeq!(TList[0], TList[1], TList[2]); | |
} | |
else | |
{ | |
static if (pred!(TList[3])) | |
alias Filter = AliasSeq!(TList[0], TList[1], TList[3]); | |
else | |
alias Filter = AliasSeq!(TList[0], TList[1]); | |
} | |
} | |
else | |
{ | |
static if (pred!(TList[2])) | |
{ | |
static if (pred!(TList[3])) | |
alias Filter = AliasSeq!(TList[0], TList[2], TList[3]); | |
else | |
alias Filter = AliasSeq!(TList[0], TList[2]); | |
} | |
else | |
{ | |
static if (pred!(TList[3])) | |
alias Filter = AliasSeq!(TList[0], TList[3]); | |
else | |
alias Filter = AliasSeq!(TList[0]); | |
} | |
} | |
} | |
else | |
{ | |
static if (pred!(TList[1])) | |
{ | |
static if (pred!(TList[2])) | |
{ | |
static if (pred!(TList[3])) | |
alias Filter = AliasSeq!(TList[1], TList[2], TList[3]); | |
else | |
alias Filter = AliasSeq!(TList[1], TList[2]); | |
} | |
else | |
{ | |
static if (pred!(TList[3])) | |
alias Filter = AliasSeq!(TList[1], TList[3]); | |
else | |
alias Filter = AliasSeq!(TList[1]); | |
} | |
} | |
else | |
{ | |
static if (pred!(TList[2])) | |
{ | |
static if (pred!(TList[3])) | |
alias Filter = AliasSeq!(TList[2], TList[3]); | |
else | |
alias Filter = AliasSeq!(TList[2]); | |
} | |
else | |
{ | |
static if (pred!(TList[3])) | |
alias Filter = AliasSeq!(TList[3]); | |
else | |
alias Filter = Nothing; | |
} | |
} | |
} | |
}); | |
private enum filterExpandFactor = FilterShortCode.length; | |
package alias Nothing = AliasSeq!(); // yes, this really does speed up compilation! | |
alias Numerics = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, | |
ulong, float, double, real, char, wchar, dchar); | |
enum convertsTo(T, U) = is(T : U); | |
alias ImplicitConversionTargets(T) = Filter!(ApplyLeft!(convertsTo, T), Numerics); | |
pragma(msg, ImplicitConversionTargets!uint); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum basic_types = ["bool", "ubyte", "char", "byte", "ushort", "wchar", "short", "uint", "dchar", "int", "ulong", "long"]; | |
// to not import stdlib | |
alias AliasSeq(T...) = T; | |
string join(string[] s, string j) { | |
string a; | |
foreach(i; s) | |
a ~= i ~ j; | |
return a; | |
} | |
template basicTypeConvTargets(T) { | |
// again, I copy/pasted your code with very slight modifications | |
string[] helper() { | |
string[] targets; | |
targets.length = basic_types.length; | |
size_t n = 0; | |
static foreach(t;basic_types) | |
{ | |
if (is(T : mixin(t))) | |
{ | |
targets[n++] = t; | |
} | |
} | |
return targets[0 .. n]; | |
} | |
mixin("alias basicTypeConvTargets = AliasSeq!(" ~ helper().join(",") ~ ");"); | |
} | |
pragma(msg, basicTypeConvTargets!ushort); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
alias type = __type__; | |
// needed to avoid deeper changes ... in the future it may be unnecessary. | |
auto makeAliasArray(type[] types ...) | |
{ | |
return types; | |
} | |
enum basic_types = makeAliasArray(bool, ubyte, char, byte, ushort, wchar, short, uint, dchar, int, ulong, long); | |
type[] convTargets(type T) | |
{ | |
if (isBasicType(T)) | |
return basicTypeConvTargets(T); | |
return null; | |
} | |
bool isBasicType(type T) | |
{ | |
foreach(t;basic_types) | |
{ | |
if (is(T == t)) | |
return true; | |
} | |
return false; | |
} | |
type[] basicTypeConvTargets(type T) | |
{ | |
type[] targets; | |
targets.length = basic_types.length; | |
assert(isBasicType(T), "You may not call this function when you don't have a basic type ... (given: " ~ T.stringof ~ ")"); | |
size_t n = 0; | |
foreach(t;basic_types) | |
{ | |
if (is(T : t)) | |
{ | |
targets[n++] = t; | |
} | |
} | |
return targets[0 .. n]; | |
} | |
pragma(msg, basicTypeConvTargets(int).tupleof); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment