blob: 20b429582b31722d9fa0aa2ec30e5246c43b69f0 [file] [log] [blame]
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Parallel extensions for mutable slices."><meta name="keywords" content="rust, rustlang, rust-lang, ParallelSliceMut"><title>ParallelSliceMut in rayon::slice - Rust</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" href="../../normalize.css"><link rel="stylesheet" href="../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../ayu.css" disabled><link rel="stylesheet" href="../../dark.css" disabled><link rel="stylesheet" href="../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../storage.js"></script><script defer src="sidebar-items.js"></script><script defer src="../../main.js"></script><noscript><link rel="stylesheet" href="../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../favicon.svg"></head><body class="rustdoc trait"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle">&#9776;</button><a class="sidebar-logo" href="../../rayon/index.html"><div class="logo-container"><img class="rust-logo" src="../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../rayon/index.html"><div class="logo-container"><img class="rust-logo" src="../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">ParallelSliceMut</a></h2><div class="sidebar-elems"><section><h3><a href="#required-methods">Required Methods</a></h3><ul class="block"><li><a href="#tymethod.as_parallel_slice_mut">as_parallel_slice_mut</a></li></ul><h3><a href="#provided-methods">Provided Methods</a></h3><ul class="block"><li><a href="#method.par_chunks_exact_mut">par_chunks_exact_mut</a></li><li><a href="#method.par_chunks_mut">par_chunks_mut</a></li><li><a href="#method.par_rchunks_exact_mut">par_rchunks_exact_mut</a></li><li><a href="#method.par_rchunks_mut">par_rchunks_mut</a></li><li><a href="#method.par_sort">par_sort</a></li><li><a href="#method.par_sort_by">par_sort_by</a></li><li><a href="#method.par_sort_by_cached_key">par_sort_by_cached_key</a></li><li><a href="#method.par_sort_by_key">par_sort_by_key</a></li><li><a href="#method.par_sort_unstable">par_sort_unstable</a></li><li><a href="#method.par_sort_unstable_by">par_sort_unstable_by</a></li><li><a href="#method.par_sort_unstable_by_key">par_sort_unstable_by_key</a></li><li><a href="#method.par_split_mut">par_split_mut</a></li></ul><h3><a href="#foreign-impls">Implementations on Foreign Types</a></h3><ul class="block"><li><a href="#impl-ParallelSliceMut%3CT%3E-for-%5BT%5D">[T]</a></li></ul><h3><a href="#implementors">Implementors</a></h3></section><h2><a href="index.html">In rayon::slice</a></h2></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><div class="search-container"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../wheel.svg"></a></div></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Trait <a href="../index.html">rayon</a>::<wbr><a href="index.html">slice</a>::<wbr><a class="trait" href="#">ParallelSliceMut</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../src/rayon/slice/mod.rs.html#163-662">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">&#x2212;</span>]</a></span></div><div class="item-decl"><pre class="rust trait"><code>pub trait ParallelSliceMut&lt;T:&nbsp;Send&gt; {
<details class="rustdoc-toggle type-contents-toggle"><summary class="hideme"><span>Show 13 methods</span></summary> fn <a href="#tymethod.as_parallel_slice_mut" class="fnname">as_parallel_slice_mut</a>(&amp;mut self) -&gt; &amp;mut [T];
fn <a href="#method.par_split_mut" class="fnname">par_split_mut</a>&lt;P&gt;(&amp;mut self, separator: P) -&gt; <a class="struct" href="struct.SplitMut.html" title="struct rayon::slice::SplitMut">SplitMut</a>&lt;'_, T, P&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="where">where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P: Fn(&amp;T) -&gt; bool + Sync + Send</span>,
{ ... }
<span class="item-spacer"></span> fn <a href="#method.par_chunks_mut" class="fnname">par_chunks_mut</a>(&amp;mut self, chunk_size: usize) -&gt; <a class="struct" href="struct.ChunksMut.html" title="struct rayon::slice::ChunksMut">ChunksMut</a>&lt;'_, T&gt; { ... }
<span class="item-spacer"></span> fn <a href="#method.par_chunks_exact_mut" class="fnname">par_chunks_exact_mut</a>(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;mut self,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_size: usize<br>&nbsp;&nbsp;&nbsp;&nbsp;) -&gt; <a class="struct" href="struct.ChunksExactMut.html" title="struct rayon::slice::ChunksExactMut">ChunksExactMut</a>&lt;'_, T&gt; { ... }
<span class="item-spacer"></span> fn <a href="#method.par_rchunks_mut" class="fnname">par_rchunks_mut</a>(&amp;mut self, chunk_size: usize) -&gt; <a class="struct" href="struct.RChunksMut.html" title="struct rayon::slice::RChunksMut">RChunksMut</a>&lt;'_, T&gt; { ... }
<span class="item-spacer"></span> fn <a href="#method.par_rchunks_exact_mut" class="fnname">par_rchunks_exact_mut</a>(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;mut self,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_size: usize<br>&nbsp;&nbsp;&nbsp;&nbsp;) -&gt; <a class="struct" href="struct.RChunksExactMut.html" title="struct rayon::slice::RChunksExactMut">RChunksExactMut</a>&lt;'_, T&gt; { ... }
<span class="item-spacer"></span> fn <a href="#method.par_sort" class="fnname">par_sort</a>(&amp;mut self)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="where">where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T: Ord</span>,
{ ... }
<span class="item-spacer"></span> fn <a href="#method.par_sort_by" class="fnname">par_sort_by</a>&lt;F&gt;(&amp;mut self, compare: F)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="where">where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T, &amp;T) -&gt; Ordering + Sync</span>,
{ ... }
<span class="item-spacer"></span> fn <a href="#method.par_sort_by_key" class="fnname">par_sort_by_key</a>&lt;K, F&gt;(&amp;mut self, f: F)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="where">where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K: Ord,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T) -&gt; K + Sync</span>,
{ ... }
<span class="item-spacer"></span> fn <a href="#method.par_sort_by_cached_key" class="fnname">par_sort_by_cached_key</a>&lt;K, F&gt;(&amp;mut self, f: F)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="where">where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T) -&gt; K + Sync,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K: Ord + Send</span>,
{ ... }
<span class="item-spacer"></span> fn <a href="#method.par_sort_unstable" class="fnname">par_sort_unstable</a>(&amp;mut self)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="where">where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T: Ord</span>,
{ ... }
<span class="item-spacer"></span> fn <a href="#method.par_sort_unstable_by" class="fnname">par_sort_unstable_by</a>&lt;F&gt;(&amp;mut self, compare: F)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="where">where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T, &amp;T) -&gt; Ordering + Sync</span>,
{ ... }
<span class="item-spacer"></span> fn <a href="#method.par_sort_unstable_by_key" class="fnname">par_sort_unstable_by_key</a>&lt;K, F&gt;(&amp;mut self, f: F)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="where">where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K: Ord,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T) -&gt; K + Sync</span>,
{ ... }
</details>}</code></pre></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Parallel extensions for mutable slices.</p>
</div></details><h2 id="required-methods" class="small-section-header">Required Methods<a href="#required-methods" class="anchor"></a></h2><div class="methods"><details class="rustdoc-toggle method-toggle" open><summary><section id="tymethod.as_parallel_slice_mut" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#166">source</a><h4 class="code-header">fn <a href="#tymethod.as_parallel_slice_mut" class="fnname">as_parallel_slice_mut</a>(&amp;mut self) -&gt; &amp;mut [T]</h4></section></summary><div class="docblock"><p>Returns a plain mutable slice, which is used to implement the rest of
the parallel methods.</p>
</div></details></div><h2 id="provided-methods" class="small-section-header">Provided Methods<a href="#provided-methods" class="anchor"></a></h2><div class="methods"><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_split_mut" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#180-188">source</a><h4 class="code-header">fn <a href="#method.par_split_mut" class="fnname">par_split_mut</a>&lt;P&gt;(&amp;mut self, separator: P) -&gt; <a class="struct" href="struct.SplitMut.html" title="struct rayon::slice::SplitMut">SplitMut</a>&lt;'_, T, P&gt;<span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;P: Fn(&amp;T) -&gt; bool + Sync + Send,</span></h4></section></summary><div class="docblock"><p>Returns a parallel iterator over mutable subslices separated by
elements that match the separator.</p>
<h5 id="examples"><a href="#examples">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>array = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">0</span>, <span class="number">2</span>, <span class="number">4</span>, <span class="number">8</span>, <span class="number">0</span>, <span class="number">3</span>, <span class="number">6</span>, <span class="number">9</span>];
array.par_split_mut(|i| <span class="kw-2">*</span>i == <span class="number">0</span>)
.for_each(|slice| slice.reverse());
<span class="macro">assert_eq!</span>(array, [<span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">8</span>, <span class="number">4</span>, <span class="number">2</span>, <span class="number">0</span>, <span class="number">9</span>, <span class="number">6</span>, <span class="number">3</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_chunks_mut" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#207-210">source</a><h4 class="code-header">fn <a href="#method.par_chunks_mut" class="fnname">par_chunks_mut</a>(&amp;mut self, chunk_size: usize) -&gt; <a class="struct" href="struct.ChunksMut.html" title="struct rayon::slice::ChunksMut">ChunksMut</a>&lt;'_, T&gt;</h4></section></summary><div class="docblock"><p>Returns a parallel iterator over at most <code>chunk_size</code> elements of
<code>self</code> at a time. The chunks are mutable and do not overlap.</p>
<p>If the number of elements in the iterator is not divisible by
<code>chunk_size</code>, the last chunk may be shorter than <code>chunk_size</code>. All
other chunks will have that exact length.</p>
<h5 id="examples-1"><a href="#examples-1">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>array = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>];
array.par_chunks_mut(<span class="number">2</span>)
.for_each(|slice| slice.reverse());
<span class="macro">assert_eq!</span>(array, [<span class="number">2</span>, <span class="number">1</span>, <span class="number">4</span>, <span class="number">3</span>, <span class="number">5</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_chunks_exact_mut" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#229-232">source</a><h4 class="code-header">fn <a href="#method.par_chunks_exact_mut" class="fnname">par_chunks_exact_mut</a>(&amp;mut self, chunk_size: usize) -&gt; <a class="struct" href="struct.ChunksExactMut.html" title="struct rayon::slice::ChunksExactMut">ChunksExactMut</a>&lt;'_, T&gt;</h4></section></summary><div class="docblock"><p>Returns a parallel iterator over <code>chunk_size</code> elements of
<code>self</code> at a time. The chunks are mutable and do not overlap.</p>
<p>If <code>chunk_size</code> does not divide the length of the slice, then the
last up to <code>chunk_size-1</code> elements will be omitted and can be
retrieved from the remainder function of the iterator.</p>
<h5 id="examples-2"><a href="#examples-2">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>array = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>];
array.par_chunks_exact_mut(<span class="number">3</span>)
.for_each(|slice| slice.reverse());
<span class="macro">assert_eq!</span>(array, [<span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">4</span>, <span class="number">5</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_rchunks_mut" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#251-254">source</a><h4 class="code-header">fn <a href="#method.par_rchunks_mut" class="fnname">par_rchunks_mut</a>(&amp;mut self, chunk_size: usize) -&gt; <a class="struct" href="struct.RChunksMut.html" title="struct rayon::slice::RChunksMut">RChunksMut</a>&lt;'_, T&gt;</h4></section></summary><div class="docblock"><p>Returns a parallel iterator over at most <code>chunk_size</code> elements of <code>self</code> at a time,
starting at the end. The chunks are mutable and do not overlap.</p>
<p>If the number of elements in the iterator is not divisible by
<code>chunk_size</code>, the last chunk may be shorter than <code>chunk_size</code>. All
other chunks will have that exact length.</p>
<h5 id="examples-3"><a href="#examples-3">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>array = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>];
array.par_rchunks_mut(<span class="number">2</span>)
.for_each(|slice| slice.reverse());
<span class="macro">assert_eq!</span>(array, [<span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">5</span>, <span class="number">4</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_rchunks_exact_mut" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#273-276">source</a><h4 class="code-header">fn <a href="#method.par_rchunks_exact_mut" class="fnname">par_rchunks_exact_mut</a>(&amp;mut self, chunk_size: usize) -&gt; <a class="struct" href="struct.RChunksExactMut.html" title="struct rayon::slice::RChunksExactMut">RChunksExactMut</a>&lt;'_, T&gt;</h4></section></summary><div class="docblock"><p>Returns a parallel iterator over <code>chunk_size</code> elements of <code>self</code> at a time,
starting at the end. The chunks are mutable and do not overlap.</p>
<p>If <code>chunk_size</code> does not divide the length of the slice, then the
last up to <code>chunk_size-1</code> elements will be omitted and can be
retrieved from the remainder function of the iterator.</p>
<h5 id="examples-4"><a href="#examples-4">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>array = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>];
array.par_rchunks_exact_mut(<span class="number">3</span>)
.for_each(|slice| slice.reverse());
<span class="macro">assert_eq!</span>(array, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">5</span>, <span class="number">4</span>, <span class="number">3</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_sort" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#311-316">source</a><h4 class="code-header">fn <a href="#method.par_sort" class="fnname">par_sort</a>(&amp;mut self)<span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;T: Ord,</span></h4></section></summary><div class="docblock"><p>Sorts the slice in parallel.</p>
<p>This sort is stable (i.e., does not reorder equal elements) and <em>O</em>(<em>n</em> * log(<em>n</em>)) worst-case.</p>
<p>When applicable, unstable sorting is preferred because it is generally faster than stable
sorting and it doesn’t allocate auxiliary memory.
See <a href="#method.par_sort_unstable"><code>par_sort_unstable</code></a>.</p>
<h5 id="current-implementation"><a href="#current-implementation">Current implementation</a></h5>
<p>The current algorithm is an adaptive merge sort inspired by
<a href="https://en.wikipedia.org/wiki/Timsort">timsort</a>.
It is designed to be very fast in cases where the slice is nearly sorted, or consists of
two or more sorted sequences concatenated one after another.</p>
<p>Also, it allocates temporary storage the same size as <code>self</code>, but for very short slices a
non-allocating insertion sort is used instead.</p>
<p>In order to sort the slice in parallel, the slice is first divided into smaller chunks and
all chunks are sorted in parallel. Then, adjacent chunks that together form non-descending
or descending runs are concatenated. Finally, the remaining chunks are merged together using
parallel subdivision of chunks and parallel merge operation.</p>
<h5 id="examples-5"><a href="#examples-5">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>v = [-<span class="number">5</span>, <span class="number">4</span>, <span class="number">1</span>, -<span class="number">3</span>, <span class="number">2</span>];
v.par_sort();
<span class="macro">assert_eq!</span>(v, [-<span class="number">5</span>, -<span class="number">3</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">4</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_sort_by" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#372-379">source</a><h4 class="code-header">fn <a href="#method.par_sort_by" class="fnname">par_sort_by</a>&lt;F&gt;(&amp;mut self, compare: F)<span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T, &amp;T) -&gt; Ordering + Sync,</span></h4></section></summary><div class="docblock"><p>Sorts the slice in parallel with a comparator function.</p>
<p>This sort is stable (i.e., does not reorder equal elements) and <em>O</em>(<em>n</em> * log(<em>n</em>)) worst-case.</p>
<p>The comparator function must define a total ordering for the elements in the slice. If
the ordering is not total, the order of the elements is unspecified. An order is a
total order if it is (for all <code>a</code>, <code>b</code> and <code>c</code>):</p>
<ul>
<li>total and antisymmetric: exactly one of <code>a &lt; b</code>, <code>a == b</code> or <code>a &gt; b</code> is true, and</li>
<li>transitive, <code>a &lt; b</code> and <code>b &lt; c</code> implies <code>a &lt; c</code>. The same must hold for both <code>==</code> and <code>&gt;</code>.</li>
</ul>
<p>For example, while [<code>f64</code>] doesn’t implement [<code>Ord</code>] because <code>NaN != NaN</code>, we can use
<code>partial_cmp</code> as our sort function when we know the slice doesn’t contain a <code>NaN</code>.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>floats = [<span class="number">5f64</span>, <span class="number">4.0</span>, <span class="number">1.0</span>, <span class="number">3.0</span>, <span class="number">2.0</span>];
floats.par_sort_by(|a, b| a.partial_cmp(b).unwrap());
<span class="macro">assert_eq!</span>(floats, [<span class="number">1.0</span>, <span class="number">2.0</span>, <span class="number">3.0</span>, <span class="number">4.0</span>, <span class="number">5.0</span>]);</code></pre></div>
<p>When applicable, unstable sorting is preferred because it is generally faster than stable
sorting and it doesn’t allocate auxiliary memory.
See <a href="#method.par_sort_unstable_by"><code>par_sort_unstable_by</code></a>.</p>
<h5 id="current-implementation-1"><a href="#current-implementation-1">Current implementation</a></h5>
<p>The current algorithm is an adaptive merge sort inspired by
<a href="https://en.wikipedia.org/wiki/Timsort">timsort</a>.
It is designed to be very fast in cases where the slice is nearly sorted, or consists of
two or more sorted sequences concatenated one after another.</p>
<p>Also, it allocates temporary storage the same size as <code>self</code>, but for very short slices a
non-allocating insertion sort is used instead.</p>
<p>In order to sort the slice in parallel, the slice is first divided into smaller chunks and
all chunks are sorted in parallel. Then, adjacent chunks that together form non-descending
or descending runs are concatenated. Finally, the remaining chunks are merged together using
parallel subdivision of chunks and parallel merge operation.</p>
<h5 id="examples-6"><a href="#examples-6">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>v = [<span class="number">5</span>, <span class="number">4</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>];
v.par_sort_by(|a, b| a.cmp(b));
<span class="macro">assert_eq!</span>(v, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]);
<span class="comment">// reverse sorting
</span>v.par_sort_by(|a, b| b.cmp(a));
<span class="macro">assert_eq!</span>(v, [<span class="number">5</span>, <span class="number">4</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_sort_by_key" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#419-425">source</a><h4 class="code-header">fn <a href="#method.par_sort_by_key" class="fnname">par_sort_by_key</a>&lt;K, F&gt;(&amp;mut self, f: F)<span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;K: Ord,<br>&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T) -&gt; K + Sync,</span></h4></section></summary><div class="docblock"><p>Sorts the slice in parallel with a key extraction function.</p>
<p>This sort is stable (i.e., does not reorder equal elements) and <em>O</em>(<em>m</em> * <em>n</em> * log(<em>n</em>))
worst-case, where the key function is <em>O</em>(<em>m</em>).</p>
<p>For expensive key functions (e.g. functions that are not simple property accesses or
basic operations), <a href="#method.par_sort_by_cached_key"><code>par_sort_by_cached_key</code></a> is likely to
be significantly faster, as it does not recompute element keys.</p>
<p>When applicable, unstable sorting is preferred because it is generally faster than stable
sorting and it doesn’t allocate auxiliary memory.
See <a href="#method.par_sort_unstable_by_key"><code>par_sort_unstable_by_key</code></a>.</p>
<h5 id="current-implementation-2"><a href="#current-implementation-2">Current implementation</a></h5>
<p>The current algorithm is an adaptive merge sort inspired by
<a href="https://en.wikipedia.org/wiki/Timsort">timsort</a>.
It is designed to be very fast in cases where the slice is nearly sorted, or consists of
two or more sorted sequences concatenated one after another.</p>
<p>Also, it allocates temporary storage the same size as <code>self</code>, but for very short slices a
non-allocating insertion sort is used instead.</p>
<p>In order to sort the slice in parallel, the slice is first divided into smaller chunks and
all chunks are sorted in parallel. Then, adjacent chunks that together form non-descending
or descending runs are concatenated. Finally, the remaining chunks are merged together using
parallel subdivision of chunks and parallel merge operation.</p>
<h5 id="examples-7"><a href="#examples-7">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>v = [-<span class="number">5i32</span>, <span class="number">4</span>, <span class="number">1</span>, -<span class="number">3</span>, <span class="number">2</span>];
v.par_sort_by_key(|k| k.abs());
<span class="macro">assert_eq!</span>(v, [<span class="number">1</span>, <span class="number">2</span>, -<span class="number">3</span>, <span class="number">4</span>, -<span class="number">5</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_sort_by_cached_key" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#467-516">source</a><h4 class="code-header">fn <a href="#method.par_sort_by_cached_key" class="fnname">par_sort_by_cached_key</a>&lt;K, F&gt;(&amp;mut self, f: F)<span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T) -&gt; K + Sync,<br>&nbsp;&nbsp;&nbsp;&nbsp;K: Ord + Send,</span></h4></section></summary><div class="docblock"><p>Sorts the slice in parallel with a key extraction function.</p>
<p>During sorting, the key function is called at most once per element, by using
temporary storage to remember the results of key evaluation.
The key function is called in parallel, so the order of calls is completely unspecified.</p>
<p>This sort is stable (i.e., does not reorder equal elements) and <em>O</em>(<em>m</em> * <em>n</em> + <em>n</em> * log(<em>n</em>))
worst-case, where the key function is <em>O</em>(<em>m</em>).</p>
<p>For simple key functions (e.g., functions that are property accesses or
basic operations), <a href="#method.par_sort_by_key"><code>par_sort_by_key</code></a> is likely to be
faster.</p>
<h5 id="current-implementation-3"><a href="#current-implementation-3">Current implementation</a></h5>
<p>The current algorithm is based on <a href="https://github.com/orlp/pdqsort">pattern-defeating quicksort</a> by Orson Peters,
which combines the fast average case of randomized quicksort with the fast worst case of
heapsort, while achieving linear time on slices with certain patterns. It uses some
randomization to avoid degenerate cases, but with a fixed seed to always provide
deterministic behavior.</p>
<p>In the worst case, the algorithm allocates temporary storage in a <code>Vec&lt;(K, usize)&gt;</code> the
length of the slice.</p>
<p>All quicksorts work in two stages: partitioning into two halves followed by recursive
calls. The partitioning phase is sequential, but the two recursive calls are performed in
parallel. Finally, after sorting the cached keys, the item positions are updated sequentially.</p>
<h5 id="examples-8"><a href="#examples-8">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>v = [-<span class="number">5i32</span>, <span class="number">4</span>, <span class="number">32</span>, -<span class="number">3</span>, <span class="number">2</span>];
v.par_sort_by_cached_key(|k| k.to_string());
<span class="macro">assert!</span>(v == [-<span class="number">3</span>, -<span class="number">5</span>, <span class="number">2</span>, <span class="number">32</span>, <span class="number">4</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_sort_unstable" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#550-555">source</a><h4 class="code-header">fn <a href="#method.par_sort_unstable" class="fnname">par_sort_unstable</a>(&amp;mut self)<span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;T: Ord,</span></h4></section></summary><div class="docblock"><p>Sorts the slice in parallel, but might not preserve the order of equal elements.</p>
<p>This sort is unstable (i.e., may reorder equal elements), in-place
(i.e., does not allocate), and <em>O</em>(<em>n</em> * log(<em>n</em>)) worst-case.</p>
<h5 id="current-implementation-4"><a href="#current-implementation-4">Current implementation</a></h5>
<p>The current algorithm is based on <a href="https://github.com/orlp/pdqsort">pattern-defeating quicksort</a> by Orson Peters,
which combines the fast average case of randomized quicksort with the fast worst case of
heapsort, while achieving linear time on slices with certain patterns. It uses some
randomization to avoid degenerate cases, but with a fixed seed to always provide
deterministic behavior.</p>
<p>It is typically faster than stable sorting, except in a few special cases, e.g., when the
slice consists of several concatenated sorted sequences.</p>
<p>All quicksorts work in two stages: partitioning into two halves followed by recursive
calls. The partitioning phase is sequential, but the two recursive calls are performed in
parallel.</p>
<h5 id="examples-9"><a href="#examples-9">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>v = [-<span class="number">5</span>, <span class="number">4</span>, <span class="number">1</span>, -<span class="number">3</span>, <span class="number">2</span>];
v.par_sort_unstable();
<span class="macro">assert_eq!</span>(v, [-<span class="number">5</span>, -<span class="number">3</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">4</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_sort_unstable_by" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#611-618">source</a><h4 class="code-header">fn <a href="#method.par_sort_unstable_by" class="fnname">par_sort_unstable_by</a>&lt;F&gt;(&amp;mut self, compare: F)<span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T, &amp;T) -&gt; Ordering + Sync,</span></h4></section></summary><div class="docblock"><p>Sorts the slice in parallel with a comparator function, but might not preserve the order of
equal elements.</p>
<p>This sort is unstable (i.e., may reorder equal elements), in-place
(i.e., does not allocate), and <em>O</em>(<em>n</em> * log(<em>n</em>)) worst-case.</p>
<p>The comparator function must define a total ordering for the elements in the slice. If
the ordering is not total, the order of the elements is unspecified. An order is a
total order if it is (for all <code>a</code>, <code>b</code> and <code>c</code>):</p>
<ul>
<li>total and antisymmetric: exactly one of <code>a &lt; b</code>, <code>a == b</code> or <code>a &gt; b</code> is true, and</li>
<li>transitive, <code>a &lt; b</code> and <code>b &lt; c</code> implies <code>a &lt; c</code>. The same must hold for both <code>==</code> and <code>&gt;</code>.</li>
</ul>
<p>For example, while [<code>f64</code>] doesn’t implement [<code>Ord</code>] because <code>NaN != NaN</code>, we can use
<code>partial_cmp</code> as our sort function when we know the slice doesn’t contain a <code>NaN</code>.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>floats = [<span class="number">5f64</span>, <span class="number">4.0</span>, <span class="number">1.0</span>, <span class="number">3.0</span>, <span class="number">2.0</span>];
floats.par_sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
<span class="macro">assert_eq!</span>(floats, [<span class="number">1.0</span>, <span class="number">2.0</span>, <span class="number">3.0</span>, <span class="number">4.0</span>, <span class="number">5.0</span>]);</code></pre></div>
<h5 id="current-implementation-5"><a href="#current-implementation-5">Current implementation</a></h5>
<p>The current algorithm is based on <a href="https://github.com/orlp/pdqsort">pattern-defeating quicksort</a> by Orson Peters,
which combines the fast average case of randomized quicksort with the fast worst case of
heapsort, while achieving linear time on slices with certain patterns. It uses some
randomization to avoid degenerate cases, but with a fixed seed to always provide
deterministic behavior.</p>
<p>It is typically faster than stable sorting, except in a few special cases, e.g., when the
slice consists of several concatenated sorted sequences.</p>
<p>All quicksorts work in two stages: partitioning into two halves followed by recursive
calls. The partitioning phase is sequential, but the two recursive calls are performed in
parallel.</p>
<h5 id="examples-10"><a href="#examples-10">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>v = [<span class="number">5</span>, <span class="number">4</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>];
v.par_sort_unstable_by(|a, b| a.cmp(b));
<span class="macro">assert_eq!</span>(v, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]);
<span class="comment">// reverse sorting
</span>v.par_sort_unstable_by(|a, b| b.cmp(a));
<span class="macro">assert_eq!</span>(v, [<span class="number">5</span>, <span class="number">4</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>]);</code></pre></div>
</div></details><details class="rustdoc-toggle method-toggle" open><summary><section id="method.par_sort_unstable_by_key" class="method has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#655-661">source</a><h4 class="code-header">fn <a href="#method.par_sort_unstable_by_key" class="fnname">par_sort_unstable_by_key</a>&lt;K, F&gt;(&amp;mut self, f: F)<span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;K: Ord,<br>&nbsp;&nbsp;&nbsp;&nbsp;F: Fn(&amp;T) -&gt; K + Sync,</span></h4></section></summary><div class="docblock"><p>Sorts the slice in parallel with a key extraction function, but might not preserve the order
of equal elements.</p>
<p>This sort is unstable (i.e., may reorder equal elements), in-place
(i.e., does not allocate), and <em>O</em>(m * <em>n</em> * log(<em>n</em>)) worst-case,
where the key function is <em>O</em>(<em>m</em>).</p>
<h5 id="current-implementation-6"><a href="#current-implementation-6">Current implementation</a></h5>
<p>The current algorithm is based on <a href="https://github.com/orlp/pdqsort">pattern-defeating quicksort</a> by Orson Peters,
which combines the fast average case of randomized quicksort with the fast worst case of
heapsort, while achieving linear time on slices with certain patterns. It uses some
randomization to avoid degenerate cases, but with a fixed seed to always provide
deterministic behavior.</p>
<p>Due to its key calling strategy, <code>par_sort_unstable_by_key</code> is likely to be slower than
<a href="#method.par_sort_by_cached_key"><code>par_sort_by_cached_key</code></a> in cases where the key function
is expensive.</p>
<p>All quicksorts work in two stages: partitioning into two halves followed by recursive
calls. The partitioning phase is sequential, but the two recursive calls are performed in
parallel.</p>
<h5 id="examples-11"><a href="#examples-11">Examples</a></h5>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rayon::prelude::<span class="kw-2">*</span>;
<span class="kw">let </span><span class="kw-2">mut </span>v = [-<span class="number">5i32</span>, <span class="number">4</span>, <span class="number">1</span>, -<span class="number">3</span>, <span class="number">2</span>];
v.par_sort_unstable_by_key(|k| k.abs());
<span class="macro">assert_eq!</span>(v, [<span class="number">1</span>, <span class="number">2</span>, -<span class="number">3</span>, <span class="number">4</span>, -<span class="number">5</span>]);</code></pre></div>
</div></details></div><h2 id="foreign-impls" class="small-section-header">Implementations on Foreign Types<a href="#foreign-impls" class="anchor"></a></h2><details class="rustdoc-toggle implementors-toggle"><summary><section id="impl-ParallelSliceMut%3CT%3E-for-%5BT%5D" class="impl has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#664-669">source</a><a href="#impl-ParallelSliceMut%3CT%3E-for-%5BT%5D" class="anchor"></a><h3 class="code-header">impl&lt;T:&nbsp;Send&gt; <a class="trait" href="trait.ParallelSliceMut.html" title="trait rayon::slice::ParallelSliceMut">ParallelSliceMut</a>&lt;T&gt; for [T]</h3></section></summary><div class="impl-items"><section id="method.as_parallel_slice_mut" class="method trait-impl has-srclink"><a class="srclink rightside" href="../../src/rayon/slice/mod.rs.html#666-668">source</a><a href="#method.as_parallel_slice_mut" class="anchor"></a><h4 class="code-header">fn <a href="#tymethod.as_parallel_slice_mut" class="fnname">as_parallel_slice_mut</a>(&amp;mut self) -&gt; &amp;mut [T]</h4></section></div></details><h2 id="implementors" class="small-section-header">Implementors<a href="#implementors" class="anchor"></a></h2><div id="implementors-list"></div><script src="../../implementors/rayon/slice/trait.ParallelSliceMut.js" data-ignore-extern-crates="core" async></script></section></div></main><div id="rustdoc-vars" data-root-path="../../" data-current-crate="rayon" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0-nightly (5c8bff74b 2022-10-21)" ></div></body></html>