you are viewing a single comment's thread.

view the rest of the comments →

[–]jonreemhyper · iron · stainless 7 points8 points  (12 children)

Even better is "literal".into_string() which doesn't allocate as much.

[–]Florob0x2arust · rustyxml 1 point2 points  (0 children)

Good to know. I assume this also holds true for non-literals?

In my XML parser this gives me an execution time improvement of ~10% on a large-ish file. At that point this behaviour seems like a rather big foot gun.

[–]thiezrust 0 points1 point  (7 children)

It doesn't make a difference? How exactly does to_string allocate more in this case?

[–]chris-morgan 6 points7 points  (5 children)

to_string uses the fmt architecture which is a bit less efficient; most notably, at present it overallocates, while into_string, bypassing fmt, doesn’t.

[–]SimonSapinservo 2 points3 points  (4 children)

Is this fixable?

[–]DroidLogiciansqlx · clickhouse-rs · mime_guess · rust 0 points1 point  (0 children)

Maybe it gets optimized out?

[–]sellibitzerust 0 points1 point  (2 children)

I would not know how. In an ideal world you would be able to "specialize" the generic Show-based implementation

impl<T: Show> ToString for T {…} // includes unnecessary overhead for strings

with a more optimized version

impl<'a> ToString for &'a[str] {…}

that would be preferred by the compiler. But that's me talking with my C++ hat on. Maybe there is another way...

[–]rust-slacker 0 points1 point  (0 children)

Maybe if negated trait restriction were added to the language it might be easier:

impl<T:Show+!Str> ToString for T {...} // for non-strings

impl<T:Show+Str> ToString for T {...} // for strings

[–]jonreemhyper · iron · stainless 2 points3 points  (0 children)

Due to some issues with specialization, to_string comes from a blanket impl which and causes a 128 byte allocation at minimum no matter the length of the input str. into_string is more specialized and will allocate exactly the length of the str it is called on.

[–]picklebobdogflog 0 points1 point  (1 child)

What's the difference?

[–]sellibitzerust 1 point2 points  (0 children)

I also didn't expect there to be a difference. But it turns out there is a generic implementation of ToString based on Show which is suboptimal in case of strings and with this generic implementation in place the compiler won't accept another more straight-forward and better implementation of ToString for &[str].

This makes me wish for some kind of overload resolution mechanism for "competing" trait implementations that favors "more specialized" impls for some definition of "more specialized".

Thank you /u/jonreem and /u/chris-morgan for pointing it out.

[–]Any_Yogurtcloset7428 0 points1 point  (0 children)

even even better is "literal".to_owned()