Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use String::new() instead of String::from(""), "".to_string(), "".to_owned() or "".into() #53563

Merged
merged 1 commit into from
Aug 24, 2018

Conversation

matthiaskrgr
Copy link
Member

No description provided.

@rust-highfive
Copy link
Collaborator

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
Member

varkor commented Aug 21, 2018

Thanks!

@bors r+ rollup

@bors
Copy link
Contributor

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
Member

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
Member

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
Contributor

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
Member

varkor commented Aug 23, 2018

@bors r+ rollup

@bors
Copy link
Contributor

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.

None yet

6 participants