Change:
floattodecimalcommon in does this: let mut buf = [0; 1024]; let mut parts = [flt2dec::Part::Zero(0); 16]; and then passes buf and parts to flt2dec::toexactfixedstr or flt2dec::toshorteststr Looking at the docs for those functions at and the "parts" array needs to have length at least 5, right? And the "buf" array needs to be at least 800+ for the toexactfixedstr case but only 17 (MAXSIGDIGITS) for the toshorteststr case, afaict. Changing the toshorteststr case to not use the huge buffer would probably help out too. Also, it's not clear to me that the "buf" scratch buffer needs to be zero-initialized. Does it?
Note that I'm poking at this a bit.
I spun off the zeroing thing into because I have a fix for that... we may still want to make the stackframe here smaller, though.

Discussion:
mod grisu; } <ins> use std::f64; use std::io::Write; use std::vec::Vec; use test::Bencher; </ins> use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded}; use core::num::flt2dec::MAX_SIG_DIGITS;

full_decoded => panic!("expected finite, got {:?} instead", full_decoded) } } <ins> #[bench] fn bench_small_shortest(b: &mut Bencher) { let mut buf = Vec::with_capacity(20); b.iter(|| { buf.clear(); write!(&mut buf, "{}", 3.1415926f64).unwrap() }); } #[bench] fn bench_big_shortest(b: &mut Bencher) { let mut buf = Vec::with_capacity(300); b.iter(|| { buf.clear(); write!(&mut buf, "{}", f64::MAX).unwrap() }); } </ins>

// except according to those terms. use fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug}; <ins> use mem; </ins> use num::flt2dec; <ins> // Don't inline this so callers don't use the stack space this function // requires unless they have to. #[inline(never)] fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T, sign: flt2dec::Sign, precision: usize) -> Result where T: flt2dec::DecodableFloat { unsafe { let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64 let mut parts: [flt2dec::Part; 5] = mem::uninitialized(); let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, false, &mut buf, &mut parts); fmt.pad_formatted_parts(&formatted) } } // Don't inline this so callers that call both this and the above won't wind // up using the combined stack space of both functions in some cases. #[inline(never)] fn float_to_decimal_common_shortest<T>(fmt: &mut Formatter, num: &T, sign: flt2dec::Sign) -> Result where T: flt2dec::DecodableFloat { unsafe { // enough for f32 and f64 let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized(); let mut parts: [flt2dec::Part; 5] = mem::uninitialized(); let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign, 0, false, &mut buf, &mut parts); fmt.pad_formatted_parts(&formatted) } } </ins> // Common code of floating point Debug and Display. fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool) -> Result where T: flt2dec::DecodableFloat

(true,  true)  => flt2dec::Sign::MinusPlusRaw, }; <del> let mut buf = [0; 1024]; // enough for f32 and f64 let mut parts = [flt2dec::Part::Zero(0); 16]; let formatted = if let Some(precision) = fmt.precision { flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, false, &mut buf, &mut parts) </del> <ins> if let Some(precision) = fmt.precision { float_to_decimal_common_exact(fmt, num, sign, precision) </ins> } else { <del> flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign, 0, false, &mut buf, &mut parts) }; fmt.pad_formatted_parts(&formatted) </del> <ins> float_to_decimal_common_shortest(fmt, num, sign) } } // Don't inline this so callers don't use the stack space this function // requires unless they have to. #[inline(never)] fn float_to_exponential_common_exact<T>(fmt: &mut Formatter, num: &T, sign: flt2dec::Sign, precision: usize, upper: bool) -> Result where T: flt2dec::DecodableFloat { unsafe { let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64 let mut parts: [flt2dec::Part; 7] = mem::uninitialized(); let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, upper, &mut buf, &mut parts); fmt.pad_formatted_parts(&formatted) } } // Don't inline this so callers that call both this and the above won't wind // up using the combined stack space of both functions in some cases. #[inline(never)] fn float_to_exponential_common_shortest<T>(fmt: &mut Formatter, num: &T, sign: flt2dec::Sign, upper: bool) -> Result where T: flt2dec::DecodableFloat { unsafe { // enough for f32 and f64 let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized(); let mut parts: [flt2dec::Part; 7] = mem::uninitialized(); let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign, (0, 0), upper, &mut buf, &mut parts); fmt.pad_formatted_parts(&formatted) } </ins> } // Common code of floating point LowerExp and UpperExp.

true  => flt2dec::Sign::MinusPlus, }; <del> let mut buf = [0; 1024]; // enough for f32 and f64 let mut parts = [flt2dec::Part::Zero(0); 16]; let formatted = if let Some(precision) = fmt.precision { </del> <ins> if let Some(precision) = fmt.precision { </ins> // 1 integral digit + `precision` fractional digits = `precision + 1` total digits <del> flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision + 1, upper, &mut buf, &mut parts) </del> <ins> float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper) </ins> } else { <del> flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign, (0, 0), upper, &mut buf, &mut parts) }; fmt.pad_formatted_parts(&formatted) </del> <ins> float_to_exponential_common_shortest(fmt, num, sign, upper) } </ins> } macro_rules! floating {