worst-case time complexity of str.find in python
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Python's str.find() has a worst-case time complexity of O(n * m), where n is the length of the string and m is the length of the substring. However, CPython (since 3.10) uses a hybrid algorithm combining Cryer's variation of the Boyer-Moore-Horspool algorithm with elements of the Sunday algorithm, making average-case performance significantly better — often close to O(n). The naive quadratic worst case is rare in practice but can occur with pathological inputs.
How str.find Works
str.find(), str.index(), str.count(), and the in operator all use the same underlying search algorithm in CPython.
Time Complexity Analysis
Let n = length of the haystack (string being searched) and m = length of the needle (substring).
| Case | Complexity | When |
| Best case | O(n/m) | Boyer-Moore-style skipping works well |
| Average case | O(n) | Typical text with varied characters |
| Worst case | O(n * m) | Pathological patterns with many partial matches |
Worst-Case Example
At each starting position, the search matches 999 a's before failing on the b. With ~1,000,000 starting positions and ~1,000 comparisons each, this requires ~10^9 character comparisons.
CPython's Implementation
CPython (3.10+) uses a sophisticated approach documented in Objects/stringlib/fastsearch.h:
Benchmarking
Comparison with Other Algorithms
| Algorithm | Worst Case | Average Case | Space |
| Naive (brute force) | O(n * m) | O(n * m) | O(1) |
| CPython str.find | O(n * m) | O(n) | O(1) |
| KMP (Knuth-Morris-Pratt) | O(n + m) | O(n + m) | O(m) |
| Boyer-Moore | O(n * m) | O(n/m) | O(m + σ) |
| Rabin-Karp | O(n * m) | O(n + m) | O(1) |
KMP guarantees O(n + m) worst case but CPython does not use it because:
- The average case of Boyer-Moore-Horspool is faster (sublinear)
- KMP requires O(m) preprocessing space
- Worst-case inputs are rare in real-world text
When str.find Is Slow
Alternatives for Performance-Critical Code
The in Operator
The in operator uses the same algorithm as str.find:
Common Pitfalls
- Assuming O(n) always:
str.find()is O(n) on average but O(n*m) worst case. For security-sensitive code processing untrusted input, an attacker could craft pathological strings. - Repeated searches: Calling
str.find()in a loop to find all occurrences is O(n * k) where k is the number of matches. Usere.finditer()orstr.count()for finding all matches. str.findvsre.search: For simple substring search,str.find()is faster than regex. Only use regex when you need pattern matching.- Unicode complexity:
str.find()operates on code points, not bytes. For ASCII text, each comparison is O(1). For multi-byte Unicode, the constant factor is larger. - CPython vs other implementations: PyPy, Jython, and other Python implementations may use different search algorithms. Performance characteristics vary.
Summary
str.find()worst case is O(n * m), average case is O(n)- CPython uses Boyer-Moore-Horspool with bloom filter optimization since Python 3.10
- Worst case occurs with pathological inputs (repeated characters + near-match patterns)
- The
inoperator,str.index(), andstr.count()all use the same algorithm - For guaranteed linear time, implement KMP or use specialized libraries
- In practice,
str.find()is fast enough for virtually all real-world text processing
Related reading
- Worst case for QuickSort - when can it occur?
- Worst case in Max-Heapify - How do you get 2n/3?
- Would Java indexOf brute force method be more practical for me or some other substring algorithm?
- Would this algorithm run in On?
- Worst input for given regular expression
- Wrapping StopWatch timing with a delegate or lambda?
- Wrap long lines in Python
- Wrapping a C library in Python C, Cython or ctypes?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.