On Wednesday, July 04, 2012 21:33:31 Andrei Alexandrescu wrote: > Great. Could you please post some code so we play with it? Thanks.
Okay. You can use this: ---------- import std.array; import std.conv; import std.datetime; import std.range; import std.stdio; import std.string; import std.traits; import std.utf; auto consumeFront(R)(ref R range) if(isInputRange!R && !isNarrowString!R) { assert(!range.empty); auto retval = range.front; range.popFront(); return retval; } auto consumeFront(R)(ref R range) if(isNarrowString!R) { size_t index = 0; auto retval = decode(range, index); range = range[index .. $]; return retval; } void main() { auto origASCII = "hello world, 1234567"; auto origUni = "ウェブサイト@La_Verité.com"; void f1() { auto arr = origASCII; while(!arr.empty) { auto f = arr.front; arr.popFront(); } } void f2() { auto arr = origASCII; while(!arr.empty) auto f = arr.consumeFront(); } void f3() { auto arr = origUni; while(!arr.empty) { auto f = arr.front; arr.popFront(); } } void f4() { auto arr = origUni; while(!arr.empty) auto f = arr.consumeFront(); } auto result = benchmark!(f1, f2, f3, f4)(10_000_000); auto percentage1 = format("%2.02f%%", 100 * result[1].to!("hnsecs", real) / result[0].to!("hnsecs", real)); auto percentage2 = format("%2.02f%%", 100 * result[3].to!("hnsecs", real) / result[2].to!("hnsecs", real)); writefln("ascii %s:%s old [%s], new [%s]", percentage1, std.array.replicate(" ", 7 - percentage1.length), to!Duration(result[0]), to!Duration(result[1])); writefln("uni %s:%s old [%s], new [%s]", percentage2, std.array.replicate(" ", 7 - percentage2.length), to!Duration(result[2]), to!Duration(result[3])); } ---------- Just adjust the strings to try different strings, and adjust then number of iterations if you need to. It prints out a two lines looking like: ascii 82.89%: old [5 secs, 176 ms, 602 μs, and 8 hnsecs], new [4 secs, 290 ms, 683 μs, and 6 hnsecs] uni 74.78%: old [6 secs, 876 ms, 3 μs, and 1 hnsec], new [5 secs, 141 ms, 955 μs, and 6 hnsecs] where the percentage is the percentage of time that consumeFront uses of the time that front and popFront take separately. To make dealing with the various combinations of compiler flags easier, I started using this script: ---------- #!/bin/bash SRC=$1 TEST=test TEST_R=testR TEST_RO=testRO TEST_ROI=testROI echo "dmd -w ${SRC} -of${TEST}" dmd -w "${SRC}" -of"${TEST}" || exit 1 ./"${TEST}" ./"${TEST}" ./"${TEST}" echo "" echo "dmd -w -release ${SRC} -of${TEST_R}" dmd -w -release "${SRC}" -of"${TEST_R}" || exit 1 ./"${TEST_R}" ./"${TEST_R}" ./"${TEST_R}" echo "" echo "dmd -w -release -O ${SRC} -of${TEST_RO}" dmd -w -release -O "${SRC}" -of"${TEST_RO}" || exit 1 ./"${TEST_RO}" ./"${TEST_RO}" ./"${TEST_RO}" echo "" echo "dmd -w -release -O -inline ${SRC} -of${TEST_ROI}" dmd -w -release -O -inline "${SRC}" -of"${TEST_ROI}" || exit 1 ./"${TEST_ROI}" ./"${TEST_ROI}" ./"${TEST_ROI}" ---------- You pass it the file that you want to compile, and it'll compile it with different combinations of compiler flags and run each combination 3 times. It shows that consumeFront is clearly faster, but the timings vary a fair bit. - Jonathan M Davis