DIP10005: Dependency-Carrying Declarations is now available for community feedback
Chris Wright via Digitalmars-d
digitalmars-d at puremagic.com
Fri Dec 23 18:23:53 PST 2016
tldr: the performance impact of this DIP would be too small to easily
measure and only impacts 26 declarations referencing 14 templates in the
standard library anyway.
On Fri, 23 Dec 2016 18:55:25 -0500, Andrei Alexandrescu wrote:
>> I grant that everyone uses phobos, and phobos uses template constraints
>> a lot. If it's *just* a problem inside phobos, though, there's another
>> obvious solution: split up modules that tend to house a lot of template
>> constraints. Split up the modules that use a wide variety of template
>> constraints.
>
> This point is discussed carefully in DIP1005. Please let me know if
> anything needs to be added.
An estimate for the actual impact on phobos, since that's your primary
driver for the change -- both under the status quo and if we try to split
modules.
The comparison to mach.d is a strawman. When I thought this might be a
problem within phobos, I thought we'd probably split std.traits and maybe
std.meta up, probably into 2-5 modules each. Not 150 lines per module;
more like 1500 to 4000 lines per module.
Then I looked at the code.
Phobos has 26 templates that would use this special syntax, referencing
14 distinct templates and CTFE functions in three modules.
If you kept the same ratios as are found in mach.d, you'd have one file
for every template used as a constraint outside its own module, one for
everything else, and as many files again with nothing in them.
The templates that have to be parsed are std.traits, std.meta, and
std.range.primitives. I wrote a test program that imported them without
using them. It compiled in too little time to accurately measure --
`time` reports 0.01s wall time.
You want to add new language syntax to save me ten milliseconds during
compilation.
You hope that template constraints become more common. If they do, this
change relies on:
* projects defining their own constraints (not just using std.traits)
* those constraints being defined in modules other than where they're used
* those constraints being defined in very large modules
* my code not depending on anything in those constraint-defining modules
* my code depending on something in a file with a template with one of
those constraints
* this whole situation being common enough to give me a death by a
thousand papercuts
If any project aside from the standard library has a 7k line module
defining things mainly used in template constraints, something is
seriously weird. But on the plus side, it would only cost me 10
milliseconds. Now, if *dozens* of projects did that, well, I'd be running
to the relative simplicity of Java APIs long before I worried about
compilation speed.
> Lazier compilation is indeed a projected benefit of this DIP. I did not
> want to dilute the thrust of the proposal with a remote promise.
Lazier compilation would *obviate* this DIP. Lazy compilation of
selective and static imports would not require any parser changes and
would make a lot of code faster (at the cost of allowing some things that
don't compile to start compiling, as does your proposal). You can't get
any performance advantages outside templates without implementing lazy
imports.
Appendix A: templates that would receive 'with(import foo)' in Phobos.
I used a relatively simple regex to look for this. If someone put more
than one line between a template and its constraints, or comments with
certain formatting, I may have missed it. However, that would violate the
phobos style guide.
This doesn't include templates that use constraints defined in their own
modules, because that module must already be parsed and no efficiency
gains could be realized.
It also omits a few cases where the module has a strong reason to import
the dependency aside from template constraints. I believe this was only
two constraints defined in std.digest, used in one or two other modules.
algorithm/comparison.d:98:template among(values...)
experimental/typecons.d:82:private template implementsInterface(Source,
Targets...)
experimental/typecons.d:94: template implementsInterface()
experimental/typecons.d:126:private template implementsInterface(Source,
Targets...)
experimental/typecons.d:184:template wrap(Targets...)
experimental/typecons.d:237: template wrap(Source)
range/package.d:2069:template Take(R)
range/package.d:3501:template Cycle(R)
range/interfaces.d:277:template MostDerivedInputRange(R)
range/interfaces.d:336:template InputRangeObject(R)
numeric.d:678:template FPTemporary(F)
conv.d:3894:template octal(alias decimalInteger)
utf.d:1136:package template codeUnitLimit(S)
typecons.d:1779:private mixin template RebindableCommon(T, U, alias This)
typecons.d:1838:template Rebindable(T)
typecons.d:4239:template wrap(Targets...)
typecons.d:4252: template wrap(Source)
typecons.d:4412:template wrap(Targets...)
typecons.d:4429:template unwrap(Target)
typecons.d:4461:template unwrap(Target)
format.d:657:template FormatSpec(Char)
algorithm/iteration.d:1055:template filter(alias predicate) if (is(typeof
(unaryFun!predicate)))
internal/math/biguintcore.d:81:template maxBigDigits(T) if (isIntegral!T)
meta.d:248:package template OldAlias(T) if (!isAggregateType!T || is
(Unqual!T == T))
meta.d:254:package template OldAlias(T) if (isAggregateType!T && !is
(Unqual!T == T))
utf.d:3542:template byUTF(C) if (isSomeChar!C)
Appendix B: templates that would need to be extracted out in phobos, if
parsing their modules cost a non-negligible amount of time.
std.meta:
allSatisfy
anySatisfy
ApplyLeft
std.range.primitives:
hasSlicing
isInputRange
isInfinite
std.traits:
isAggregateType
isAssociativeArray
isDynamicArray
isFloatingPoint
isImplicitlyConvertible
isIntegral
isMutable
isSomeChar
More information about the Digitalmars-d
mailing list