Surprisingly, startswith slower than in :
In [10]: s="ABCD"*10 In [11]: %timeit s.startswith("XYZ") 1000000 loops, best of 3: 307 ns per loop In [12]: %timeit "XYZ" in s 10000000 loops, best of 3: 81.7 ns per loop
As we all know, the in operation should look for the entire string, and startswith just needs to check the first few characters, so startswith should be more efficient.
When s is large enough, startswith is faster:
In [13]: s="ABCD"*200 In [14]: %timeit s.startswith("XYZ") 1000000 loops, best of 3: 306 ns per loop In [15]: %timeit "XYZ" in s 1000000 loops, best of 3: 666 ns per loop
So it seems that the startswith call has some overhead, which makes it slower when the line is small.
And than I tried to figure out what the overhead of calling startswith .
First, I used the variable f to reduce the cost of the dot operation โ as indicated in this โ here we see that startswith is still slower:
In [16]: f=s.startswith In [17]: %timeit f("XYZ") 1000000 loops, best of 3: 270 ns per loop
In addition, I checked the cost of an empty function call:
In [18]: def func(a): pass In [19]: %timeit func("XYZ") 10000000 loops, best of 3: 106 ns per loop
Regardless of the cost of the point operation and the function call, the startswith time is about (270-106) = 164 ns, but the in operation takes only 81.7 ns. There seems to be some more overhead for startswith what is it?
Add a test result between startswith and __contains__ , as suggested by poke and lvc:
In [28]: %timeit s.startswith("XYZ") 1000000 loops, best of 3: 314 ns per loop In [29]: %timeit s.__contains__("XYZ") 1000000 loops, best of 3: 192 ns per loop