Conversation
src/doc/complement-cheatsheet.md
Outdated
src/libstd/num/fmt.rs
Outdated
There was a problem hiding this comment.
Neat trick!
However, it doesn't seem to support arbitrary bases. What about these being normal methods fn base(&self) -> u8 (etc.) and having
pub struct Binary;
impl Radix for Binary { fn base(&self) -> u8 { 2 } /* ... */ }
pub struct Octal;
// ...
pub struct GenericRadix { priv base: u8 }
impl Radix for GenerixRadix { fn radix(&self) { self.base } /* ... */ }which would give the best of both worlds: static dispatch for the common cases but still enough flexibility to handle arbitrary bases. (And also allows for reducing code-bloat via choosing to use the GenericRadix version over monomorphising for the others, similar to a &Radix trait object, but without the extra cost of virtual calls.)
There was a problem hiding this comment.
Hey that's a cool idea. Will do.
|
Sweet perf wins. 🚀 |
src/libstd/num/fmt.rs
Outdated
There was a problem hiding this comment.
It may be a bit faster if you accumulate the digits backwards starting at the end of the buffer. That way you only need to make one write call to the underlying Writer.
There was a problem hiding this comment.
WOAH. Mega improvement. Writing an int with a decimal radix now takes 204 ns, down from 640 ns with strconv.
There was a problem hiding this comment.
Awesome! (Remember to update the PR/commit messages before it lands :) )
|
Cool stuff. It reminds me that I ought to dust off the floating point formatting code that I had written a few weeks ago. |
|
Yeah, I'm looking at the Dragon4 (Steele) and Grisu3 (Loitsch) algorithms when it comes to formatting floating point. But you're welcome to look at it too. It's much more complicated than the integer stuff :) |
|
@alexcrichton Ok, I think I'm done. |
src/libstd/fmt/mod.rs
Outdated
There was a problem hiding this comment.
This comment seems copied from below, there seems to be no check against the "maximum width" which I think in the case of integers is precision.
|
This is super awesome. Perf wins, cleanups, hurrah! I'd like to bikeshed the interface for a brief amount of time if that's ok. Some thoughts I have:
What do you think? |
|
Ok, updated the API and moved it to You can now do: assert_eq!(format!("{:04}", radix(3, 2)), ~"0011");I haven't made the other things private, because I still think its useful to be able to write the numbers via a |
src/libstd/fmt/mod.rs
Outdated
There was a problem hiding this comment.
This use may need to be updated. I think it'd be useful to show it in the documentation as well.
Could you also expand the documentation a bit about how the value can be passed to format! to format the specified integer with the specified base?
This is PR is the beginning of a complete rewrite and ultimate removal of the
std::num::strconvmodule (see #6220), and the removal of theToStrRadixtrait in favour of using thestd::fmtfunctionality directly. This should make for a cleaner API, encourage less allocation, and make the implementation more comprehensible .The
Formatter::{pad_integral, with_padding}methods have also been refactored make things easier to understand.The formatting tests for integers have been moved out of
run-pass/ifmt.rsin order to provide more immediate feedback when building usingmake check-stage2-std NO_REBUILD=1.Arbitrary radixes are now easier to use in format strings. For example:
The benchmarks have been standardised between
std::num::strconvandstd::num::fmtto make it easier to compare the performance of the different implementations.