Skip to content

Conversation

matthiaskrgr
Copy link
Member

No description provided.

@rust-highfive
Copy link
Contributor

r? @varkor

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 21, 2018
@matthiaskrgr
Copy link
Member Author

Motivation: rust-lang/rust-clippy#2972

@varkor
Copy link
Contributor

varkor commented Aug 21, 2018

Thanks!

@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Aug 21, 2018

📌 Commit e97ccd89d8b2d5f5c9038a293f19a474358b3404 has been approved by varkor

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 21, 2018
@killercup
Copy link
Contributor

Another option would be to make "".to_string() call String::new(). I have never looked at the code so I don't know what issues this may have.

But following the breadcrumbs…

rust/src/liballoc/string.rs

Lines 2160 to 2165 in 70c33bb

impl ToString for str {
#[inline]
fn to_string(&self) -> String {
String::from(self)
}
}

rust/src/liballoc/string.rs

Lines 2200 to 2204 in 70c33bb

impl<'a> From<&'a str> for String {
fn from(s: &'a str) -> String {
s.to_owned()
}
}

rust/src/liballoc/str.rs

Lines 206 to 208 in 70c33bb

fn to_owned(&self) -> String {
unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) }
}

…it seems we could try to add a if bytes.is_empty() { return String::new() } here and see what happens:

rust/src/liballoc/string.rs

Lines 731 to 733 in 70c33bb

pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
String { vec: bytes }
}

@matthiaskrgr
Copy link
Member Author

Mh yes, I also wondered if there was some way to have some sort of shortcut.
But i was not sure how expensive the .is_empty() check would be.

Is there some way to only emit the check if we know the input of the function is a constant and is guaranteed to be optimized out (by always taking the return String::new() codepath)?

@killercup
Copy link
Contributor

killercup commented Aug 21, 2018

Is there some way to only emit the check if we know the input of the function is a constant and is guaranteed to be optimized out (by always taking the return String::new() codepath)?

I think this would require dependent types, or all the functions I quoted to be const fn

Edit: Oh, and self.as_bytes().to_owned() is most likely calling clone on a Vec<u8> -- this could also be optimized to not allocate zero bytes (maybe it even already is)

Edit2: Well…

rust/src/liballoc/vec.rs

Lines 1686 to 1688 in a9d4967

fn clone(&self) -> Vec<T> {
<[T]>::to_vec(&**self)
}

rust/src/liballoc/slice.rs

Lines 365 to 370 in a9d4967

pub fn to_vec(&self) -> Vec<T>
where T: Clone
{
// NB see hack module in this file
hack::to_vec(self)
}

rust/src/liballoc/slice.rs

Lines 164 to 171 in a9d4967

pub fn to_vec<T>(s: &[T]) -> Vec<T>
where T: Clone
{
let mut vector = Vec::with_capacity(s.len());
vector.extend_from_slice(s);
vector
}
}

@nagisa
Copy link
Member

nagisa commented Aug 21, 2018

@matthiaskrgr The check for empty allocation is already done by "".as_bytes().to_owned() and already does avoid the allocation. The problem is that neither String::from() nor "".to_owned() are inlined. I suspect that’s entirely the cause of whatever the benchmark in the clippy issue measured.

@matthiaskrgr
Copy link
Member Author

Oh, that's interesting!

When I tried setting a very high (9999....) or very low (1, 0) inline threshold on godbolt I still can't get String::from() to be inlined though. 😕
https://rust.godbolt.org/z/xDC-aW

@nagisa
Copy link
Member

nagisa commented Aug 21, 2018

We’ll just have to add #[inline]s on the from and to_owned methods to make them available for inlining.

bors added a commit that referenced this pull request Aug 22, 2018
Rollup of 10 pull requests

Successful merges:

 - #53418 (Mark some suggestions as MachineApplicable)
 - #53431 (Moved some feature gate ui tests to correct location)
 - #53442 (Update version of rls-data used with save-analysis)
 - #53504 (Set applicability for more suggestions.)
 - #53541 (Fix missing impl trait display as ret type)
 - #53544 (Point at the trait argument when using unboxed closure)
 - #53558 (Normalize source line and column numbers.)
 - #53562 (Lament the invincibility of the Turbofish)
 - #53574 (Suggest direct raw-pointer dereference)
 - #53585 (Remove super old comment on function that parses items)

Failed merges:

 - #53472 (Use FxHash{Map,Set} instead of the default Hash{Map,Set} everywhere in rustc.)
 - #53563 (use String::new() instead of String::from(""), "".to_string(), "".to_owned() or "".into())

r? @ghost
@bors
Copy link
Collaborator

bors commented Aug 22, 2018

☔ The latest upstream changes (presumably #53607) made this pull request unmergeable. Please resolve the merge conflicts.

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 22, 2018
@matthiaskrgr
Copy link
Member Author

rebased
@varkor r?

@varkor
Copy link
Contributor

varkor commented Aug 23, 2018

@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Aug 23, 2018

📌 Commit ede1f7d has been approved by varkor

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 23, 2018
kennytm added a commit to kennytm/rust that referenced this pull request Aug 24, 2018
use String::new() instead of String::from(""), "".to_string(), "".to_owned() or "".into()
bors added a commit that referenced this pull request Aug 24, 2018
Rollup of 16 pull requests

Successful merges:

 - #53311 (Window Mutex: Document that we properly initialize the SRWLock)
 - #53503 (Discourage overuse of mem::forget)
 - #53545 (Fix #50865: ICE on impl-trait returning functions reaching private items)
 - #53559 (add macro check for lint)
 - #53562 (Lament the invincibility of the Turbofish)
 - #53563 (use String::new() instead of String::from(""), "".to_string(), "".to_owned() or "".into())
 - #53592 (docs: minor stylistic changes to str/string docs)
 - #53594 (Update RELEASES.md to include clippy-preview)
 - #53600 (Fix a grammatical mistake in "expected generic arguments" errors)
 - #53614 (update nomicon and book)
 - #53617 (tidy: Stop requiring a license header)
 - #53618 (Add missing fmt examples)
 - #53636 (Prefer `.nth(n)` over `.skip(n).next()`.)
 - #53644 (Use SmallVec for SmallCStr)
 - #53664 (Remove unnecessary closure in rustc_mir/build/mod.rs)
 - #53666 (Added rustc_codegen_llvm to compiler documentation.)
@bors bors merged commit ede1f7d into rust-lang:master Aug 24, 2018
@matthiaskrgr matthiaskrgr deleted the String branch August 28, 2018 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants