On Thu, Jul 13, 2017 at 04:16:50PM -0400, Steven Schveighoffer via Digitalmars-d wrote: [...] > http://www.schveiguy.com/blog/2016/05/have-your-voldemort-types-and-keep-your-disk-space-too/ > > I was surprised as well at the reduction. I only noticed the problem > because when I was debugging my library, the program was taking an > unreasonably long time to *print a stack trace* (like multiple > seconds). [...]
Whoa. I just tried your 'horcrux' trick, and discovered that it causes a further reduction in executable size! Original sizes: 38144296 bytes (38.1 MB) 61412056 bytes (61.4 MB) After factoring out Voldemort structs as module-global private structs: 8332352 bytes (8.3 MB) 10376584 bytes (10.4 MB) After further refactoring to use the "horcrux" trick: 8147392 bytes (8.1 MB) 10124136 bytes (10.1 MB) While this last reduction is rather modest relative to the total executable sizes, it still represents a reduction of 200KB and 300KB worth of symbols(!) each. Given that this code base is a mere 5000+ LOC, I'd expect significant savings in larger template-heavy projects. My guess as to reason for this reduction is because now you only have to instantiate one template for each template function call, rather than two: private struct MyFuncImpl(Args...) { ... } auto myFunc(Args...)(Args args) { return MyFuncImpl!Args(args); } will instantiate two templates, MyFuncImpl and myFunc, each time with the same argument list; whereas: template myFunc(Args...) { auto myFunc(Args args) { return Impl(args); } struct Impl { ... } } only requires a single template instantiation of myFunc, since Impl is instantiated along with the function itself. There's also the slightly shorter names involved (`myFunc!Args.Impl` vs. `MyFuncImpl!Args.MyFuncImpl`), which, given the O(n^2) or O(n^3) symbol length dependency, can quickly add up to non-trivial amounts of savings. T -- Those who don't understand D are condemned to reinvent it, poorly. -- Daniel N