-
Notifications
You must be signed in to change notification settings - Fork 13.6k
fmt of non-decimal radix untangled #143730
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
base: master
Are you sure you want to change the base?
Conversation
2281143
to
d593c6f
Compare
This comment has been minimized.
This comment has been minimized.
d593c6f
to
f0f1c53
Compare
This comment has been minimized.
This comment has been minimized.
f0f1c53
to
76b8c3a
Compare
☔ The latest upstream changes (presumably #144044) made this pull request unmergeable. Please resolve the merge conflicts. |
76b8c3a
to
110d35e
Compare
Can you either have a look or reassign @tgross35? Got a followup pending on this one... |
I'll reassign for now, but if nobody beats me to it I'll take a look on Monday r? libs (leaving myself assigned so it stays on my list) |
By the way; if you are interested, we could use some int (and float) formatting and parsing benchmarks at https://github.com/rust-lang/rustc-perf/blob/2120e3b7b8996e96858b88edefea371679a3d415/collector/runtime-benchmarks/fmt/src/main.rs (I just learned that is possible), which would mean they get run as part of our pretty extensive perf infra rather than you needing to post the results of local runs. |
Interesting indeed @tgross35. The specialized benchmarks we have at the moment (such as |
* correct buffer size * no trait abstraction * similar to decimal
110d35e
to
2c6210d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few notes, haven't looked at patches 3 & 4 yet
fn to_u64(&self) -> u64; | ||
fn to_u128(&self) -> u128; | ||
} | ||
// Formatting of integers with a non-decimal radix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, might as well make it a doc comment
// Formatting of integers with a non-decimal radix. | |
/// Formatting of integers with a non-decimal radix. |
library/core/src/fmt/num.rs
Outdated
(fmt::$Trait:ident for $T:ident -> $Radix:ident) => { | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl fmt::$Trait for $T { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
$Radix.fmt_int(*self as $U, f) | ||
$Radix.fmt_int(*self, f) | ||
} | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe int_base
could do both signed and unsigned rather than having the impls in integer
?
(fmt::$Trait:ident for ($Int:ident, $Uint:ident) -> $Radix:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::$Trait for $Uint {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
$Radix.fmt_int(*self as $U, f)
$Radix.fmt_int(*self, f)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::$Trait for $Int {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::$Trait::fmt(&self.cast_unsigned(), f)
}
}
};
library/core/src/fmt/num.rs
Outdated
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl fmt::Binary for $Int { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
fmt::Binary::fmt(&(*self as $Uint), f) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mentioned above but we now have .cast_unsigned()
which is slightly cleaner than as $Uint
#[bench] | ||
fn write_12ints_bin(bh: &mut Bencher) { | ||
bh.iter(|| { | ||
black_box(format!("{:b}", black_box(0_u8))); | ||
black_box(format!("{:b}", black_box(100_i8))); | ||
black_box(format!("{:b}", black_box(-100_i8))); | ||
|
||
black_box(format!("{:b}", black_box(0_u32))); | ||
black_box(format!("{:b}", black_box(1000_i32))); | ||
black_box(format!("{:b}", black_box(-1000_i32))); | ||
|
||
black_box(format!("{:b}", black_box(0_u64))); | ||
black_box(format!("{:b}", black_box(10000_i64))); | ||
black_box(format!("{:b}", black_box(-10000_i64))); | ||
|
||
black_box(format!("{:b}", black_box(0_u128))); | ||
black_box(format!("{:b}", black_box(100000_i128))); | ||
black_box(format!("{:b}", black_box(-100000_i128))); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to break up benchmarks by integer size because that can be pretty platform-dependent, e.g. u64 might be about the same as u32 on 64-bit platforms, but significantly slower on 32-bit.
Testing a few assorted values seems good though. To get an even balance it may also be good to check:
1 << n
for n0..U::BITS
, both signed and unsigned10.pow(n)
forn = 0
up to the max that fitsI::MIN
,I::MAX
,U::MAX
These can be collected outside of bb.iter
so the cost of computing values isn't included in the benchmarks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is preexisting but it would also be better to create a String::with_capacity(enough_for_u128)
, within bb.iter
just .clear()
and write!
into it. Keeps time to alloc/free from skewing benchmark results.
Have the implementation match its decimal counterpart.
Original Performance
Patched Performance
r? tgross35