Timsort is a
hybrid,
stable
A stable is a building in which working animals are kept, especially horses or oxen. The building is usually divided into stalls, and may include storage for equipment and feed.
Styles
There are many different types of stables in use tod ...
sorting algorithm
In computer science, a sorting algorithm is an algorithm that puts elements of a List (computing), list into an Total order, order. The most frequently used orders are numerical order and lexicographical order, and either ascending or descending ...
, derived from
merge sort
In computer science, merge sort (also commonly spelled as mergesort and as ) is an efficient, general-purpose, and comparison sort, comparison-based sorting algorithm. Most implementations of merge sort are Sorting algorithm#Stability, stable, wh ...
and
insertion sort
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time by comparisons. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. Howev ...
, designed to perform well on many kinds of real-world data. It was implemented by
Tim Peters in 2002 for use in the
Python programming language
Python is a high-level, general-purpose programming language. Its design philosophy emphasizes code readability with the use of significant indentation.
Python is dynamically type-checked and garbage-collected. It supports multiple prog ...
. The algorithm finds subsequences of the data that are already ordered (runs) and uses them to sort the remainder more efficiently. This is done by merging runs until certain criteria are fulfilled. Timsort has been Python's standard sorting algorithm since version 2.3, and starting with 3.11 it uses Timsort with the
Powersort merge policy.
Timsort is also used to sort arrays of non-primitive type in
Java SE 7, on the
Android platform, in
GNU Octave
GNU Octave is a scientific programming language for scientific computing and numerical computation. Octave helps in solving linear and nonlinear problems numerically, and for performing other numerical experiments using a language that is mostly ...
, on
V8, in
Swift
Swift or SWIFT most commonly refers to:
* SWIFT, an international organization facilitating transactions between banks
** SWIFT code
* Swift (programming language)
* Swift (bird), a family of birds
It may also refer to:
Organizations
* SWIF ...
, and
Rust
Rust is an iron oxide, a usually reddish-brown oxide formed by the reaction of iron and oxygen in the catalytic presence of water or air moisture. Rust consists of hydrous iron(III) oxides (Fe2O3·nH2O) and iron(III) oxide-hydroxide (FeO(OH) ...
.
It uses techniques from Peter McIlroy's 1993 paper "Optimistic Sorting and Information Theoretic Complexity".
Operation
Timsort was designed to take advantage of ''runs'' of consecutive ordered elements that already exist in most real-world data, ''natural runs''. It iterates over the data collecting elements into runs and simultaneously putting those runs in a stack. Whenever the runs on the top of the stack match a
merge criterion, they are merged. This goes on until all data is traversed; then, all runs are merged two at a time and only one sorted run remains. The advantage of merging ordered runs instead of merging fixed size sub-lists (as done by traditional mergesort) is that it decreases the total number of comparisons needed to sort the entire list.
Each run has a minimum size, which is based on the size of the input and is defined at the start of the algorithm. If a run is smaller than this minimum run size,
insertion sort
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time by comparisons. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. Howev ...
is used to add more elements to the run until the minimum run size is reached.
Merge criteria

Timsort is a stable sorting algorithm (order of elements with same key is kept) and strives to perform balanced merges (a merge thus merges runs of similar sizes).
In order to achieve sorting stability, only consecutive runs are merged. Between two non-consecutive runs, there can be an element with the same key inside the runs. Merging those two runs would change the order of equal keys. Example of this situation ([] are ordered runs): [1 2 2] 1 4 2 [0 1 2]
In pursuit of balanced merges, Timsort considers three runs on the top of the stack, ''X'', ''Y'', ''Z'', and maintains the invariants:
If any of these invariants is violated, ''Y'' is merged with the smaller of ''X'' or ''Z'' and the invariants are checked again. Once the invariants hold, the search for a new run in the data can start.
These invariants maintain merges as being approximately balanced while maintaining a compromise between delaying merging for balance, exploiting fresh occurrence of runs in
cache memory
In computing, a cache ( ) is a hardware or software component that stores data so that future requests for that data can be served faster; the data stored in a cache might be the result of an earlier computation or a copy of data stored elsew ...
and making merge decisions relatively simple.
Merge space overhead

The original merge sort implementation is not in-place and it has a space overhead of N (data size). In-place merge sort implementations exist, but have a high time overhead. In order to achieve a middle term, Timsort performs a merge sort with a small time overhead and smaller space overhead than N.
First, Timsort performs a
binary search
In computer science, binary search, also known as half-interval search, logarithmic search, or binary chop, is a search algorithm that finds the position of a target value within a sorted array. Binary search compares the target value to the m ...
to find the location where the first element of the second run would be inserted in the first ordered run, keeping it ordered. Then, it performs the same algorithm to find the location where the last element of the first run would be inserted in the second ordered run, keeping it ordered. Elements before and after these locations are already in their correct place and do not need to be merged. Then, the smaller of these shrunk runs is copied into temporary memory, and the copied elements are merged with the larger shrunk run into the now free space. If the leftmost shrunk run is smaller, the merge proceeds from left to right. If the rightmost shrunk run is smaller, merging proceeds from right to left (i.e. beginning with elements at the ends of the temporary space and leftmost run, and filling the free space from its end). This optimization reduces the number of required element movements, the running time and the temporary space overhead in the general case.
Example: two runs
, 2, 3, 6, 10and
, 5, 7, 9, 12, 14, 17must be merged. Note that both runs are already sorted individually. The smallest element of the second run is 4 and it would have to be added at the fourth position of the first run in order to preserve its order (assuming that the first position of a run is 1). The largest element of the first run is 10 and it would have to be added at the fifth position of the second run in order to preserve its order. Therefore,
, 2, 3and
2, 14, 17are already in their final positions and the runs in which elements movements are required are
, 10and
, 5, 7, 9 With this knowledge, we only need to allocate a temporary buffer of size 2 instead of 4.
Merge direction
Merging can be done in both directions: left-to-right, as in the traditional mergesort, or right-to-left.
Galloping mode during merge

An individual merge of runs R1 and R2 keeps the count of consecutive elements selected from a run. When this number reaches the ''minimum galloping threshold'' (''min_gallop''), Timsort considers that it is likely that many consecutive elements may still be selected from that run and switches into galloping mode. Let us assume that R1 is responsible for triggering it. In this mode, the algorithm performs a two-stage search for the place in the run R1 where the next element ''x'' of the run R2 would be inserted. In the first stage it performs an
exponential search
In computer science, an exponential search (also called doubling search or galloping search or Struzik search) is an algorithm, created by Jon Bentley and Andrew Chi-Chih Yao in 1976, for searching sorted, unbounded/infinite lists. There are nu ...
, also known as a galloping search, until finding a ''k'' such that R1
''k−1'' − 1">''k−1'' − 1< x <= R1
''k'' − 1">''k'' − 1 i.e. a region of uncertainty comprising 2
''k−1'' − 1 consecutive elements of R1. The second stage performs a straight binary search of this region to find the exact location in R1 for ''x''. Galloping mode is an attempt to adapt the merge algorithm to the pattern of intervals between elements in runs.
Galloping is not always efficient. In some cases galloping mode requires more comparisons than a simple
linear search
In computer science, linear search or sequential search is a method for finding an element within a list. It sequentially checks each element of the list until a match is found or the whole list has been searched.
A linear search runs in linea ...
. According to benchmarks done by the developer, galloping is beneficial only when the initial element of one run is not one of the first seven elements of the other run. This implies an initial threshold of 7. To avoid the drawbacks of galloping mode, two actions are taken: (1) When galloping is found to be less efficient than
binary search
In computer science, binary search, also known as half-interval search, logarithmic search, or binary chop, is a search algorithm that finds the position of a target value within a sorted array. Binary search compares the target value to the m ...
, galloping mode is exited. (2)
The success or failure of galloping is used to adjust ''min_gallop''. If the selected element is from the same array that returned an element previously, ''min_gallop'' is reduced by one, thus encouraging the return to galloping mode. Otherwise, the value is incremented by one, thus discouraging a return to galloping mode. In the case of random data, the value of ''min_gallop'' becomes so large that galloping mode never recurs.
Descending runs
In order to also take advantage of data sorted in descending order, Timsort reverses strictly descending runs when it finds them and adds them to the stack of runs. Since descending runs are later blindly reversed, excluding runs with equal elements maintains the algorithm's stability; i.e., equal elements won't be reversed.
Minimum run size

Because merging is most efficient when the number of runs is equal to, or slightly less than, a power of two, and notably less efficient when the number of runs is slightly more than a power of two, Timsort chooses ''minrun'' to try to ensure the former condition.
''Minrun'' is chosen from the range 32 to 64 inclusive, such that the size of the data, divided by ''minrun'', is equal to, or slightly less than, a power of two. The final algorithm takes the six most significant bits of the size of the array, adds one if any of the remaining bits are set, and uses that result as the ''minrun''. This algorithm works for all arrays, including those smaller than 64; for arrays of size 63 or less, this sets ''minrun'' equal to the array size and Timsort reduces to an insertion sort.
Algorithm
Below is an iterative implementation of Timsort, written in
Pseudocode
In computer science, pseudocode is a description of the steps in an algorithm using a mix of conventions of programming languages (like assignment operator, conditional operator, loop) with informal, usually self-explanatory, notation of actio ...
. Note that a function call is made to
insertionSort
, this is a standard implementation of
Insertion sort
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time by comparisons. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. Howev ...
which is used to sort arrays between two defined pointers. The pseudocode for this function is also given.
function TimSort(array arr) is
n ← length(arr)
run ← 32
i ← 0
left ← 0
size ← run
while i < n do
tmp ← min(i + run - 1, n - 1)
insertionSort(arr, i, tmp)
i ← i + run
while size < n do
while left < n do
mid ← left + size - 1
right = min(left + 2 * size - 1, n - 1)
if mid < right then
merge(arr, left, mid, right)
left ← left + 2 * size
left ← 0
size ← size * 2
function insertionSort(array arr, int left, int right) is
i ← left + 1
while i <= right do
tmp ← arr
j ← i - 1
while j >= left and arr
> tmp do
arr
+ 1← arr
j ← j - 1
arr
+ 1= tmp
i ← i + 1
Below is the function
merge
which performs the merging of runs found in the array to be sorted.
function merge(array arr, int l, int m, int r) is
x, y, i, j, k ← 0
y ← 0
len1 ← m - l + 1
len2 ← r - m
left ← new array of length equal to len1
right ← new array of length equal to len2
while x < len1 do
left
← arr
+ x x ← x + 1
while y < len2 do
right
← arr
m + 1) + y y ← y + 1
// Merge the left and right arrays.
while i < len1 and j < len2 do
if left
<= right
then
arr
+ k← left
i ← i + 1
else
arr
+ k← right
j ← j + 1
k ← k + 1
// Copy the remaining elements of left, if any.
while i < len1 do
arr
+ k← left
k ← k + 1
i ← i + 1
// Copy remaining elements of right, if any.
while j < len2 do
arr
+ k← right
k ← k + 1
j ← j + 1
Analysis
In the
worst case
In computer science, best, worst, and average cases of a given algorithm express what the resource usage is ''at least'', ''at most'' and ''on average'', respectively. Usually the resource being considered is running time, i.e. time complexity, b ...
, Timsort takes
comparisons to sort an array of
elements. In the best case, which occurs when the input is already sorted, it runs in linear time, meaning that it is an
adaptive sorting algorithm.
For an input that has
runs of sorted elements, the running time is
. More strongly, the time is
, where the
entropy
Entropy is a scientific concept, most commonly associated with states of disorder, randomness, or uncertainty. The term and the concept are used in diverse fields, from classical thermodynamics, where it was first recognized, to the micros ...
of an input in which the
th run has size
is defined to be
[ When all run sizes are equal, the entropy is , its maximum value for any given number of runs, but it can be smaller when the runs have unevenly distributed sizes. The formula for the running time is given as rather than more simply , to account for the possibility that the entropy can be less than one.][
]
Formal verification
In 2015, Dutch and German researchers in the EU FP7 ENVISAGE project found a bug in the standard implementation of Timsort. It was fixed in 2015 in Python, Java, and Android.
Specifically, the invariants on stacked run sizes ensure a tight upper bound on the maximum size of the required stack. The implementation preallocated a stack sufficient to sort 264 bytes of input, and avoided further overflow checks.
However, the guarantee requires the invariants to apply to ''every'' group of three consecutive runs, but the implementation only checked it for the top three.[ Using the KeY tool for ]formal verification
In the context of hardware and software systems, formal verification is the act of proving or disproving the correctness of a system with respect to a certain formal specification or property, using formal methods of mathematics.
Formal ver ...
of Java software, the researchers found that this check is not sufficient, and they were able to find run lengths (and inputs which generated those run lengths) which would result in the invariants being violated deeper in the stack after the top of the stack was merged.
As a consequence, for certain inputs the allocated size is not sufficient to hold all unmerged runs. In Java, this generates for those inputs an array-out-of-bound exception. The smallest input that triggers this exception in Java and Android v7 is of size (226). (Older Android versions already triggered this exception for certain inputs of size (216))
The Java implementation was corrected by increasing the size of the preallocated stack based on an updated worst-case analysis. The article also showed by formal methods how to establish the intended invariant by checking that the ''four'' topmost runs in the stack satisfy the two rules above. This approach was initially adopted by PythonPython Issue Tracker – Issue 23515: Bad logic in timsort's merge_collapse
/ref> until it switched to Powersort in 2022 with the release of Python 3.11.
References
Further reading
*
External links
timsort.txt
– original explanation by Tim Peters
{{Sorting
Comparison sorts
Stable sorts