Compile-time optimization

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Jul 23 11:09:24 PDT 2013


On Tue, Jul 23, 2013 at 06:21:08PM +0200, JS wrote:
> There seems to be a lot of improvement for programming languages to
> optimize compile time aspects that are not taken into account. With
> ctfe I think such optimizations are more and more relevant in D.
[...]
> But there should be no reason why join(["a", "b", "c"]) can't be
> optimized at compile time so that the function call is replaced with
> "abc".
[...]
> To generate such "optimal" code(one that gets the compiler to do as
> much work as it can at compile time) is somewhat convoluted in D. We
> can use string mixins to solve the problem but not easily because we
> can't pass variadic arguments to templates.
> 
> e.g.,
> 
> join(T...)(T s)
> {
>     mixin(tJoinH!(s))
> }
> 
> fails because s is not known at compile time... even if s is
> partially known.
[...]

Your CTFE-fu isn't good enough. ;-) Check this out:

	import std.stdio;

	template tuple(args...) {
		alias tuple = args;
	}

	/**
	 * Given a tuple of strings, returns a tuple in which all
	 * adjacent compile-time readable strings are concatenated.
	 */
	template tupleReduce(args...)
	{
		static if (args.length > 1)
		{
			static if (is(typeof(args[0])==string) &&
				__traits(compiles, { enum x = args[0]; }))
			{
				static if (is(typeof(args[1])==string) &&
					__traits(compiles, { enum x = args[1]; }))
				{
					alias tupleReduce = tupleReduce!(args[0] ~
								args[1], args[2..$]);
				}
				else
				{
					alias tupleReduce = tuple!(args[0], args[1],
								tupleReduce!(args[2..$]));
				}
			}
			else
			{
				alias tupleReduce = tuple!(args[0],
							tupleReduce!(args[1..$]));
			}
		}
		else
		{
			alias tupleReduce = args;
		}
	}

	void main() {
		string x = "runtime1";
		string y = "runtime2";
		auto arr = [ tupleReduce!("a", "b", x, "c", "d", y, "e", "f") ];
		writeln(arr);
	}

The output is:

	["ab", "runtime1", "cd", "runtime2", "ef"]

which proves that all adjacent compile-time readable strings have been
concatenated at compile-time.

Using tupleReduce, you can optimize calls to join by writing:

	join(tupleReduce!("a", "b", x, "c", "d"));

and it will be compiled as though you've written:

	join("ab", x, "cd");

Yeah, so tupleReduce looks a bit on the ugly side. But the point is that
it works. So don't be so quick to say something is not possible in D,
'cos even with its current warts, D is one powerful beast.  :-)


T

-- 
One disk to rule them all, One disk to find them. One disk to bring them
all and in the darkness grind them. In the Land of Redmond where the
shadows lie. -- The Silicon Valley Tarot


More information about the Digitalmars-d mailing list