Skip to content

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

Merged
bors merged 1 commit into
rust-lang:masterfrom
matthiaskrgr:String
Aug 24, 2018
Merged

use String::new() instead of String::from(""), "".to_string(), "".to_owned() or "".into()#53563
bors merged 1 commit into
rust-lang:masterfrom
matthiaskrgr:String

Conversation

@matthiaskrgr

Copy link
Copy Markdown
Member

No description provided.

@rust-highfive

Copy link
Copy Markdown
Contributor

r? @varkor

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

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

Copy link
Copy Markdown
MemberAuthor

Motivation: rust-lang/rust-clippy#2972

@varkor

Copy link
Copy Markdown
Contributor

Thanks!

@bors r+ rollup

@bors

bors commented Aug 21, 2018

Copy link
Copy Markdown
Collaborator

📌 Commit e97ccd89d8b2d5f5c9038a293f19a474358b3404 has been approved by varkor

@borsbors 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
Copy Markdown
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

implToStringforstr{
#[inline]
fnto_string(&self) -> String{
String::from(self)
}
}

rust/src/liballoc/string.rs

Lines 2200 to 2204 in 70c33bb

impl<'a>From<&'astr>forString{
fnfrom(s:&'astr) -> String{
s.to_owned()
}
}

rust/src/liballoc/str.rs

Lines 206 to 208 in 70c33bb

fnto_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:

pubunsafefnfrom_utf8_unchecked(bytes:Vec<u8>) -> String{
String{vec: bytes }
}

@matthiaskrgr

Copy link
Copy Markdown
MemberAuthor

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

killercup commented Aug 21, 2018

Copy link
Copy Markdown
Contributor

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

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

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

pubfnto_vec<T>(s:&[T]) -> Vec<T>
whereT:Clone
{
letmut vector = Vec::with_capacity(s.len());
vector.extend_from_slice(s);
vector
}
}

@nagisa

Copy link
Copy Markdown
Member

@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
Copy Markdown
MemberAuthor

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
Copy Markdown
Member

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

bors commented Aug 22, 2018

Copy link
Copy Markdown
Collaborator

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

@borsbors 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
Copy Markdown
MemberAuthor

rebased
@varkor r?

@varkor

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@bors

bors commented Aug 23, 2018

Copy link
Copy Markdown
Collaborator

📌 Commit ede1f7d has been approved by varkor

@borsbors 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()
@kennytmkennytm mentioned this pull request Aug 24, 2018
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:masterAug 24, 2018
@matthiaskrgr
matthiaskrgr deleted the String branch August 28, 2018 17:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-borsStatus: 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

@matthiaskrgr@rust-highfive@varkor@bors@killercup@nagisa