On Wed, Mar 09, 2016 at 05:12:18AM -0800, Jonathan M Davis via Digitalmars-d-learn wrote: [...] > So, in general, you can slap pure on most anything, though it will > rarely buy you anything in terms of performance.
IMO, this is an area where the compiler could be improved to take better advantage of pure annotations. The currently-implemented optimizations based on pure, while nice, are also relatively rare, and don't seem to outweigh the cost of having to annotate large numbers of functions by hand. I think one area where pure could potentially have a large gain is in loop optimization, where pure annotations may help in increasing the amount of code that can be hoisted out of the loop. Contrived example: long veryExpensiveFunction(T)(T arg) pure { ... } long func(long x) { long accum; foreach (i; 0 .. 1_000_000) { accum += i*veryExpensiveFunction(x); } return accum; } If veryExpensiveFunction() is not pure, we cannot hoist it out of the loop, since it may change the program's semantics. However, if it's pure, we can potentially have a large performance gain by hoisting it outside the loop. (One may argue that a good programmer would already do this manually, of course, but the thing about these kinds of loop optimizations is that they often exhibit domino-effects, where the above code snippet isn't what the programmer actually wrote, but the result of a previous optimization on the original code, say an inlining, or some such. Having the compiler detect this case may then lead to more optimization opportunities downstream. While dmd is, IME, rather poor at following these optimization domino chains, gdc's optimizer has a lot of aggressive loop optimizations, and may be able to do much better than it can now if the frontend can feed this kind of information about purity to it.) [...] > The reason to avoid pure with templated functions is that whether a > templated function can really be pure or not usually depends on its > arguments. I think a useful pattern that has emerged in Phobos code is that all template functions, in general, should have no attributes -- it should be left to the compiler to infer them. To ensure that the code itself doesn't break purity (etc.), use a pure (etc.) unittest: auto func(T)(T args) // N.B.: no attributes { ... } pure unittest { // We know that int will not introduce impurity to // func(), so this unittest will break if func itself // contains impure code aside from its template // arguments. func(1); } This way, we ensure that the compiler will infer func as pure whenever it can, yet we don't restrict T to be also pure (in the case where T is impure, the compiler will correctly infer func!T as impure). Attribute inference is the way of the future. T -- Let's eat some disquits while we format the biskettes.