title: Why is startswith slower than slicing
body: <p>Why is the implementation of <a href="http://docs.python.org/2/library/stdtypes.html#str.startswith" rel="noreferrer"><code>startwith</code></a> slower than slicing?</p>
  
  <pre><code>In [1]: x = 'foobar'
  
  In [2]: y = 'foo'
  
  In [3]: %timeit x.startswith(y)
  1000000 loops, best of 3: 321 ns per loop
  
  In [4]: %timeit x[:3] == y
  10000000 loops, best of 3: 164 ns per loop
  </code></pre>
  
  <p>Surprisingly, even including calculation for the length, slicing still appears significantly faster:</p>
  
  <pre><code>In [5]: %timeit x[:len(y)] == y
  1000000 loops, best of 3: 251 ns per loop
  </code></pre>
  
  <p><em>Note: the first part of this behaviour is noted in <a href="http://shop.oreilly.com/product/0636920023784.do" rel="noreferrer"><strong>Python for Data Analysis</strong></a> (Chapter 3), but no explanation for it is offered.</em></p>
  
  <p>.</p>
  
  <p>If helpful: <a href="http://hg.python.org/cpython/file/4ebe1ede981e/Objects/stringobject.c#l2903" rel="noreferrer">here is the C code for <code>startswith</code></a>; and here is the output of <a href="https://stackoverflow.com/questions/12673074/how-should-i-understand-the-output-of-dis-dis"><code>dis.dis</code></a>: </p>
  
  <pre><code>In [6]: import dis
  
  In [7]: dis_it = lambda x: dis.dis(compile(x, '&lt;none&gt;', 'eval'))
  
  In [8]: dis_it('x[:3]==y')
    1           0 LOAD_NAME                0 (x)
                3 LOAD_CONST               0 (3)
                6 SLICE+2             
                7 LOAD_NAME                1 (y)
               10 COMPARE_OP               2 (==)
               13 RETURN_VALUE        
  
  In [9]: dis_it('x.startswith(y)')
    1           0 LOAD_NAME                0 (x)
                3 LOAD_ATTR                1 (startswith)
                6 LOAD_NAME                2 (y)
                9 CALL_FUNCTION            1
               12 RETURN_VALUE 
  </code></pre>