<p dir="auto">For example, as of this writing, the <code class="notranslate">StrAllocating::to_owned</code> method is annotated with <code class="notranslate">#[deprecated = "obsolete, use </code>to_string<code class="notranslate">"]</code>, but <a href="http://doc.rust-lang.org/std/str/trait.StrAllocating.html#method.to_owned" rel="nofollow">http://doc.rust-lang.org/std/str/trait.StrAllocating.html#method.to_owned</a> gives no indication of that.</p>
<p dir="auto">Platform: Windows, rust nightly.</p>
<p dir="auto">The optimizations made to fix <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="31373630" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/13472" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust/issues/13472/hovercard" href="https://github.com/rust-lang/rust/issues/13472">#13472</a> appear to have been undone by <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="37212620" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/15471" data-hovercard-type="pull_request" data-hovercard-url="/rust-lang/rust/pull/15471/hovercard" href="https://github.com/rust-lang/rust/pull/15471">#15471</a> and <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/rust-lang/rust/commit/3316b1eb7c3eb520896af489dd45c4d17190d0a8/hovercard" href="https://github.com/rust-lang/rust/commit/3316b1eb7c3eb520896af489dd45c4d17190d0a8"><tt>3316b1e</tt></a></p>
<p dir="auto">In 32-bit mode, <code class="notranslate">rustc -O --test test.rs &amp;&amp; ./test --bench</code> gives:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="running 7 tests
test clone_str                  ... bench:   1540862 ns/iter (+/- 25433)
test clone_vec_from_fn          ... bench:    745343 ns/iter (+/- 7535)
test clone_vec_from_incremental ... bench:   1088468 ns/iter (+/- 5358)
test fast_clone_vec             ... bench:    310484 ns/iter (+/- 3212)
test memory_copy                ... bench:    102162 ns/iter (+/- 1220)
test naive_clone_vec            ... bench:    745599 ns/iter (+/- 8111)"><pre class="notranslate"><code class="notranslate">running 7 tests
test clone_str                  ... bench:   1540862 ns/iter (+/- 25433)
test clone_vec_from_fn          ... bench:    745343 ns/iter (+/- 7535)
test clone_vec_from_incremental ... bench:   1088468 ns/iter (+/- 5358)
test fast_clone_vec             ... bench:    310484 ns/iter (+/- 3212)
test memory_copy                ... bench:    102162 ns/iter (+/- 1220)
test naive_clone_vec            ... bench:    745599 ns/iter (+/- 8111)
</code></pre></div>
<p dir="auto">With <del><code class="notranslate">-C target-cpu=x86-64</code></del> SSE enabled (<code class="notranslate">-C target-feature=+sse2</code>), things look better but <code class="notranslate">String::clone</code> still stands out:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="running 7 tests
test clone_str                  ... bench:   1661609 ns/iter (+/- 60586)
test clone_vec_from_fn          ... bench:    359253 ns/iter (+/- 202820)
test clone_vec_from_incremental ... bench:    357418 ns/iter (+/- 3406)
test fast_clone_vec             ... bench:    309973 ns/iter (+/- 9762)
test memory_copy                ... bench:    102129 ns/iter (+/- 1317)
test naive_clone_vec            ... bench:    753919 ns/iter (+/- 8473)"><pre class="notranslate"><code class="notranslate">running 7 tests
test clone_str                  ... bench:   1661609 ns/iter (+/- 60586)
test clone_vec_from_fn          ... bench:    359253 ns/iter (+/- 202820)
test clone_vec_from_incremental ... bench:    357418 ns/iter (+/- 3406)
test fast_clone_vec             ... bench:    309973 ns/iter (+/- 9762)
test memory_copy                ... bench:    102129 ns/iter (+/- 1317)
test naive_clone_vec            ... bench:    753919 ns/iter (+/- 8473)
</code></pre></div>
<p dir="auto">Performance seems very dependent on minor details: <code class="notranslate">clone_vec_from_incremental</code> is much slower than <code class="notranslate">clone_vec_from_fn</code> in <del>32 bit</del> non-SSE mode.</p>
<p dir="auto">Benchmark program:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="extern crate test;
extern crate core;

use test::{Bencher, black_box};
use core::ptr;

static SIZE: uint = 1024*1024;

#[bench]
fn clone_str(bh: &amp;mut Bencher) {
    let mut x = String::with_capacity(SIZE);
    for _ in range(0, SIZE) {
        x.push('x');
    }
    bh.iter(|| black_box(x.clone()));
}

#[bench]
fn clone_vec_from_incremental(bh: &amp;mut Bencher) {
    let mut x: Vec&lt;u8&gt; = Vec::with_capacity(SIZE);
    for _ in range(0, SIZE) {
        x.push(0x78);
    }
    bh.iter(|| black_box(x.clone()));
}

#[bench]
fn clone_vec_from_fn(bh: &amp;mut Bencher) {
    let x: Vec&lt;u8&gt; = Vec::from_fn(SIZE, |_| 0x78);
    bh.iter(|| black_box(x.clone()));
}

#[bench]
fn naive_clone_vec(bh: &amp;mut Bencher) {
    let x: Vec&lt;u8&gt; = Vec::from_fn(SIZE, |_| 0x78);
    bh.iter(|| {
        black_box(Vec::from_fn(SIZE, |i| x[i]));
    });
}

#[bench]
fn fast_clone_vec(bh: &amp;mut Bencher) {
    let x: Vec&lt;u8&gt; = Vec::from_fn(SIZE, |_| 0x78);
    bh.iter(|| {
        let mut copy = Vec::&lt;u8&gt;::with_capacity(SIZE);
        unsafe {
            ptr::copy_memory(copy.as_mut_ptr(), x.as_ptr(), x.len());
            copy.set_len(SIZE);
        }
        black_box(copy)
    });
}

#[bench]
fn memory_copy(bh: &amp;mut Bencher) {
    let x: Vec&lt;u8&gt; = Vec::from_fn(SIZE, |_| 0x78);
    let mut y: Vec&lt;u8&gt; = Vec::from_fn(SIZE, |_| 0);
    bh.iter(|| {
        unsafe {
            ptr::copy_memory(y.as_mut_ptr(), x.as_ptr(), x.len());
        }
    })
}"><pre class="notranslate"><span class="pl-k">extern</span> <span class="pl-k">crate</span> test<span class="pl-kos">;</span>
<span class="pl-k">extern</span> <span class="pl-k">crate</span> core<span class="pl-kos">;</span>

<span class="pl-k">use</span> test<span class="pl-kos">::</span><span class="pl-kos">{</span><span class="pl-v">Bencher</span><span class="pl-kos">,</span> black_box<span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">use</span> core<span class="pl-kos">::</span>ptr<span class="pl-kos">;</span>

<span class="pl-k">static</span> <span class="pl-v">SIZE</span><span class="pl-kos">:</span> <span class="pl-smi">uint</span> = <span class="pl-c1">1024</span><span class="pl-c1">*</span><span class="pl-c1">1024</span><span class="pl-kos">;</span>

<span class="pl-c1">#<span class="pl-kos">[</span>bench<span class="pl-kos">]</span></span>
<span class="pl-k">fn</span> <span class="pl-en">clone_str</span><span class="pl-kos">(</span><span class="pl-s1">bh</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-k">mut</span> <span class="pl-smi">Bencher</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">let</span> <span class="pl-k">mut</span> x = <span class="pl-smi">String</span><span class="pl-kos">::</span><span class="pl-en">with_capacity</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">for</span> _ <span class="pl-k">in</span> <span class="pl-en">range</span><span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-v">SIZE</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        x<span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-s">'x'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
    bh<span class="pl-kos">.</span><span class="pl-en">iter</span><span class="pl-kos">(</span>|| <span class="pl-en">black_box</span><span class="pl-kos">(</span>x<span class="pl-kos">.</span><span class="pl-en">clone</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-c1">#<span class="pl-kos">[</span>bench<span class="pl-kos">]</span></span>
<span class="pl-k">fn</span> <span class="pl-en">clone_vec_from_incremental</span><span class="pl-kos">(</span><span class="pl-s1">bh</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-k">mut</span> <span class="pl-smi">Bencher</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">let</span> <span class="pl-k">mut</span> x<span class="pl-kos">:</span> <span class="pl-smi">Vec</span><span class="pl-kos">&lt;</span><span class="pl-smi">u8</span><span class="pl-kos">&gt;</span> = <span class="pl-smi">Vec</span><span class="pl-kos">::</span><span class="pl-en">with_capacity</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">for</span> _ <span class="pl-k">in</span> <span class="pl-en">range</span><span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-v">SIZE</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        x<span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-c1">0x78</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
    bh<span class="pl-kos">.</span><span class="pl-en">iter</span><span class="pl-kos">(</span>|| <span class="pl-en">black_box</span><span class="pl-kos">(</span>x<span class="pl-kos">.</span><span class="pl-en">clone</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-c1">#<span class="pl-kos">[</span>bench<span class="pl-kos">]</span></span>
<span class="pl-k">fn</span> <span class="pl-en">clone_vec_from_fn</span><span class="pl-kos">(</span><span class="pl-s1">bh</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-k">mut</span> <span class="pl-smi">Bencher</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">let</span> x<span class="pl-kos">:</span> <span class="pl-smi">Vec</span><span class="pl-kos">&lt;</span><span class="pl-smi">u8</span><span class="pl-kos">&gt;</span> = <span class="pl-smi">Vec</span><span class="pl-kos">::</span><span class="pl-en">from_fn</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">,</span> |_| <span class="pl-c1">0x78</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    bh<span class="pl-kos">.</span><span class="pl-en">iter</span><span class="pl-kos">(</span>|| <span class="pl-en">black_box</span><span class="pl-kos">(</span>x<span class="pl-kos">.</span><span class="pl-en">clone</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-c1">#<span class="pl-kos">[</span>bench<span class="pl-kos">]</span></span>
<span class="pl-k">fn</span> <span class="pl-en">naive_clone_vec</span><span class="pl-kos">(</span><span class="pl-s1">bh</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-k">mut</span> <span class="pl-smi">Bencher</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">let</span> x<span class="pl-kos">:</span> <span class="pl-smi">Vec</span><span class="pl-kos">&lt;</span><span class="pl-smi">u8</span><span class="pl-kos">&gt;</span> = <span class="pl-smi">Vec</span><span class="pl-kos">::</span><span class="pl-en">from_fn</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">,</span> |_| <span class="pl-c1">0x78</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    bh<span class="pl-kos">.</span><span class="pl-en">iter</span><span class="pl-kos">(</span>|| <span class="pl-kos">{</span>
        <span class="pl-en">black_box</span><span class="pl-kos">(</span><span class="pl-smi">Vec</span><span class="pl-kos">::</span><span class="pl-en">from_fn</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">,</span> |i| x<span class="pl-kos">[</span>i<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-c1">#<span class="pl-kos">[</span>bench<span class="pl-kos">]</span></span>
<span class="pl-k">fn</span> <span class="pl-en">fast_clone_vec</span><span class="pl-kos">(</span><span class="pl-s1">bh</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-k">mut</span> <span class="pl-smi">Bencher</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">let</span> x<span class="pl-kos">:</span> <span class="pl-smi">Vec</span><span class="pl-kos">&lt;</span><span class="pl-smi">u8</span><span class="pl-kos">&gt;</span> = <span class="pl-smi">Vec</span><span class="pl-kos">::</span><span class="pl-en">from_fn</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">,</span> |_| <span class="pl-c1">0x78</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    bh<span class="pl-kos">.</span><span class="pl-en">iter</span><span class="pl-kos">(</span>|| <span class="pl-kos">{</span>
        <span class="pl-k">let</span> <span class="pl-k">mut</span> copy = <span class="pl-smi">Vec</span><span class="pl-kos">::</span><span class="pl-kos">&lt;</span><span class="pl-smi">u8</span><span class="pl-kos">&gt;</span><span class="pl-kos">::</span><span class="pl-en">with_capacity</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-k">unsafe</span> <span class="pl-kos">{</span>
            ptr<span class="pl-kos">::</span><span class="pl-en">copy_memory</span><span class="pl-kos">(</span>copy<span class="pl-kos">.</span><span class="pl-en">as_mut_ptr</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> x<span class="pl-kos">.</span><span class="pl-en">as_ptr</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> x<span class="pl-kos">.</span><span class="pl-en">len</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            copy<span class="pl-kos">.</span><span class="pl-en">set_len</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span>
        <span class="pl-en">black_box</span><span class="pl-kos">(</span>copy<span class="pl-kos">)</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-c1">#<span class="pl-kos">[</span>bench<span class="pl-kos">]</span></span>
<span class="pl-k">fn</span> <span class="pl-en">memory_copy</span><span class="pl-kos">(</span><span class="pl-s1">bh</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-k">mut</span> <span class="pl-smi">Bencher</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">let</span> x<span class="pl-kos">:</span> <span class="pl-smi">Vec</span><span class="pl-kos">&lt;</span><span class="pl-smi">u8</span><span class="pl-kos">&gt;</span> = <span class="pl-smi">Vec</span><span class="pl-kos">::</span><span class="pl-en">from_fn</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">,</span> |_| <span class="pl-c1">0x78</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">let</span> <span class="pl-k">mut</span> y<span class="pl-kos">:</span> <span class="pl-smi">Vec</span><span class="pl-kos">&lt;</span><span class="pl-smi">u8</span><span class="pl-kos">&gt;</span> = <span class="pl-smi">Vec</span><span class="pl-kos">::</span><span class="pl-en">from_fn</span><span class="pl-kos">(</span><span class="pl-v">SIZE</span><span class="pl-kos">,</span> |_| <span class="pl-c1">0</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    bh<span class="pl-kos">.</span><span class="pl-en">iter</span><span class="pl-kos">(</span>|| <span class="pl-kos">{</span>
        <span class="pl-k">unsafe</span> <span class="pl-kos">{</span>
            ptr<span class="pl-kos">::</span><span class="pl-en">copy_memory</span><span class="pl-kos">(</span>y<span class="pl-kos">.</span><span class="pl-en">as_mut_ptr</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> x<span class="pl-kos">.</span><span class="pl-en">as_ptr</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> x<span class="pl-kos">.</span><span class="pl-en">len</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-kos">}</span></pre></div>