Conceptintro
Constant time
Also called O(1) time.
Running time that does not grow with input size.
An algorithm runs in constant time when its running time is bounded by a constant that does not depend on the input size . In the notation of asymptotic notation, this is . It is the lowest class in the common growth rates.
In plain words
A constant-time operation takes about the same time on a small input and on a huge one. Reading the first item of a list is an example. The list can have ten items or ten billion, and the work is the same: go to the first place and read it.
This does not mean the operation is fast. It means that the cost does not grow with the size of the input. A step that takes one hour is a constant-time step, if it takes one hour for each input.
An algorithm that runs in constant time cannot look at every item of a large input, because looking at each item takes more time when there are more items. So it must use a structure that tells it where to look, such as an array index or a hash value.
The idea
Definition
Fix a cost model, for example the word RAM with unit cost for each basic operation on a word, and fix a case: worst, average, expected or amortized. Let be the cost of the algorithm in that model and case on inputs of size (see input size). The algorithm runs in constant time when
This is . When also holds for all large , then . A running time is at least one step on each input, so for a real algorithm and say the same thing. A bound always needs its case. "Worst-case " is a statement about each input. "Amortized " is a statement about a sequence of operations.
Shapes of constant-time operations
- Direct access. Reading or writing
A[i]in an array costs one address computation and one memory access in the word RAM, so it is worst-case . - Arithmetic on words. Addition, comparison and bit operations on integers of bits take one step when the word size is . See the pitfalls below for the limit of this rule.
- Fixed-size pieces of a structure. Push and pop on a stack in an array with free space, enqueue and dequeue on a queue in a circular buffer, and insertion after a known node of a linked list each change a fixed number of fields.
- Amortized constant time. Appending to a dynamic array that doubles its capacity when it is full costs amortized. Start with capacity 1 and append items. For , a copy happens when the array is full, at sizes , where is the largest integer with . For there is no copy. These copies move items. Together with the writes of the new items, the total is less than , so the amortized cost of one append is less than 3 writes. A single append that triggers a copy still costs . See array doubling and amortized vs worst case.
- Expected constant time. A lookup in a hash table with a good hash function and a bounded load factor costs in expectation. See the pitfalls below.
When the input doubles
If , then : the cost stays within the same constant bounds. The ratio stays between two positive constants, and in experiments it is usually close to 1. On a real machine the measured ratio can be well above 1 when doubling pushes the data out of a cache level (L1, L2, L3 or the TLB). This happens at large , for example at millions of items, and the word RAM does not model it.
Pitfalls
- Amortized is not worst case. A dynamic array append has amortized cost but worst-case cost . A real-time system that needs a hard bound for each operation cannot use the amortized claim. Incremental resizing, which moves a few old items on each append, gives worst-case appends, if allocating an uninitialized block takes time. See amortized vs worst case.
- Expected is not worst case. A hash table lookup is in expectation over the random choice of the hash function (or over a random input), under the assumption that the load factor is bounded. If all keys fall in one bucket and the bucket is a list, one lookup takes . Perfect hashing (Fredman, Komlós and Szemerédi, 1984) for a static set, and cuckoo hashing, look up a key in worst-case . See amortized vs expected cost.
- The word size is part of the model. Adding two integers is one step only when each fits in one word. Adding two numbers of bits takes word operations. A big-integer library, a string comparison or copying a slice is not in general. The same is true for a hash table lookup with a key of words: hashing the key and comparing it with a stored key each cost .
- A large constant is still constant. A step that costs operations on every input is . The notation does not say which of two constant-time operations is faster. Memory access costs differ by a large factor between cache and main memory, and the word RAM does not model this.
- The word in cryptography. In cryptography, "constant-time code" means code whose running time does not depend on secret values, as a defense against a timing attack. A constant-time comparison of two strings of bytes still takes time.
- Fixed-size inputs. Every algorithm is on a set of inputs with bounded size. The class is only meaningful when can grow.
- No time for the whole input. An algorithm that runs in time reads only items of the input. It cannot compute a function that depends on all items, such as the sum of an array. This is the extreme case of sublinear time.
Examples
- Read
A[i]for a given index in an array: worst-case . - Test whether an integer in a machine word is even, by testing its lowest bit: worst-case .
- Push onto a stack held in an array that has free space: worst-case . When the array is full and must grow, that one push costs . If the capacity grows by a constant factor, for example by doubling, the push is amortized . If it grows by a fixed amount, pushes cost in total, so one push is amortized .
- Look up a key in a hash table: expected , worst case for a table with chaining, worst case with static perfect hashing or cuckoo hashing.
- Non-example: find the maximum of an unsorted array. The answer depends on each item, so the time is . See linear time.
- Non-example: look up a key in a sorted array by binary search. The cost grows by one comparison each time the size doubles, so it is logarithmic, not constant.
Where it is used
Constant-time operations are the unit of cost in the word RAM and in the random access machine, and the analysis of each algorithm counts them. A data structure page gives the cost of each operation, and the best result is worst-case for each operation. When that is not possible, the page gives an amortized or an expected bound and says so. Typical constant-time queries after preprocessing are a range sum from prefix sums after preprocessing, and a range minimum query with a sparse table after preprocessing. Graph algorithms number the vertices 0 to and test membership in a boolean array in worst-case time. They use a hash set, with expected time, only when the vertex labels are not small integers.
References
- Cormen, Leiserson, Rivest and Stein, Introduction to Algorithms, fourth edition, Section 2.2 (the RAM model), Chapter 11 (hash tables) and Section 16.4 (dynamic tables)
- Robert Sedgewick and Kevin Wayne, Algorithms, fourth edition, Section 1.4
- Donald E. Knuth, The Art of Computer Programming, Volume 1, third edition, Section 1.2.11.1
- Michael L. Fredman, János Komlós and Endre Szemerédi, Storing a sparse table with O(1) worst case access time, Journal of the ACM 31 (1984), the two-level perfect hashing scheme
- Rasmus Pagh and Flemming Friche Rodler, Cuckoo hashing, Journal of Algorithms 51 (2004), worst-case constant lookup time
About this page
The build computes these levels from the evidence in the repository. Each row says what the next level needs. Read what the levels mean.
| Ladder | Level | What the next level needs |
|---|---|---|
| Human proof | H0 no proof |
|
| Lean | L0 no Lean part |
|
| Visual | V0 none |
|
| Writing | W4 complete |
|
Tag QAKMJW Edit this page History Report an error Markdown JSON