Boost logo

Boost :

Subject: Re: [boost] [iterators] Proof-of-concept for a sentinel iteratoradapter
From: Kevin Sopp (baraclese_at_[hidden])
Date: 2009-05-13 12:22:02


Interesting, I wrote a modified version where you can enter the string
length and the sentinel version is consistently slower (using
gcc-4.4.0 with -O3).

// sentinel terminated sequence iterator proof-of-concept
// Copyright Beman Dawes, 2009

#include <cassert>
#include <cstring>
#include <iostream>
#include <boost/functional/hash.hpp>
#include <boost/timer.hpp>

 // sentinel terminated sequence iterator

 template < class T, T Sentinel = T() >
 class sentinel_iterator
 {
 public:
   sentinel_iterator() : m_ptr(0) {} // construct end iterator

   sentinel_iterator( T * p ) : m_ptr( (p && *p != m_sentinel) ? p : 0 ) {}

   sentinel_iterator & operator++()
   {
     assert(m_ptr);
     if ( *++m_ptr == m_sentinel ) m_ptr = 0;
     return *this;
   }

   T & operator*() const
   {
     assert(m_ptr);
     return *m_ptr;
   }

   bool operator==( const sentinel_iterator & rhs ) const
   {
     return m_ptr == rhs.m_ptr;
   }

   bool operator!=( const sentinel_iterator & rhs ) const
   {
     return m_ptr != rhs.m_ptr;
   }

 private:
   T * m_ptr; // 0 == the end iterator
   static const T m_sentinel = Sentinel;
 };

static size_t test_strlen( const char* s )
{
  return boost::hash_range( s, s + strlen( s ) );
}

static size_t test_sentinel( const char* s )
{
  return boost::hash_range(
      sentinel_iterator< const char >( s ), sentinel_iterator< const char >() );
}

int main()
{
  const unsigned N = 1000000;

  std::cout << "enter text length: ";
  unsigned len;
  std::cin >> len;

  char* text = new char[len];
  for (unsigned i = 0; i < len; ++i)
    text[i] = '4';
  text[len] = '\0';

  std::size_t m1 = 0;
  std::size_t m2 = 0;

  {
    boost::timer t;
    for( unsigned i = 0; i < N; ++i )
    {
        m1 += test_strlen( text );
    }

    std::cout << "strlen: " << t.elapsed() << " " << m1 << std::endl;
  }

  {
    boost::timer t;
    for( unsigned i = 0; i < N; ++i )
    {
        m2 += test_sentinel( text );
    }
    std::cout << "sentinel: " << t.elapsed() << " " << m2 << std::endl;
  }

  delete[] text;

  return 0;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk