I wrote a few versions of a palindrome testing function and noticed that versions using ranges (isPalindrome1..isPalindrome3) are 3 times slower than array indexing one (isPalindrome0). Is there a more efficient way of using ranges? Timing was done on Windows with DMD 2.063.2 (32-bit) dmd -O -noboundscheck -inline -release.

// 6.9ms
bool isPalindrome0(T)(T[] s) {
   auto i = 0;
   for (; i < s.length/2 && s[i] == s[$-i-1]; ++i) {}
   return i == s.length/2;
}

// 21ms
bool isPalindrome1(T)(T[] s) {
   while (s.length > 1 && s.front == s.back) {
      s.popBack();
      s.popFront();
   }

   return s.length <= 1;
}

// 21ms
bool isPalindrome2(T)(T[] s) {
for (; s.length > 1 && s.front == s.back; s.popBack(), s.popFront()) {}
   return s.length <= 1;
}

// 21.4ms
bool isPalindrome3(T)(T s) {
   foreach (i; 0..s.length/2)
      if (s[i] != s[$-i-1])
         return false;

   return true;
}


int test() {
   int a[10];
   int n = 0;

   foreach (i; 0..1_000_000) {
      a[4] = !a[4];
      n += isPalindrome0(a);
   }

   return n;
}


void main()
{
   enum N = 16;
   auto t = benchmark!(test)(N);

   writeln(cast(float)t[0].msecs/N);
   writeln(test);
}

Reply via email to