Если вы хотите повысить производительность, вы можете создать структуру и реализовать для нее Display
или Debug
. Это позволяет избежать выделения String
. Для максимальной чрезмерной инженерии у вас также может быть выделенный в стек массив вместо Vec
.
Вот ответ Boiethios с этими изменениями:
struct Radix {
x: i32,
radix: u32,
}
impl Radix {
fn new(x: i32, radix: u32) -> Result<Self, &'static str> {
if radix < 2 || radix > 36 {
Err("Unnsupported radix")
} else {
Ok(Self { x, radix })
}
}
}
use std::fmt;
impl fmt::Display for Radix {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut x = self.x;
// Good for binary formatting of `u128`s
let mut result = ['\0'; 128];
let mut used = 0;
let negative = x < 0;
if negative {
x*=-1;
}
let mut x = x as u32;
loop {
let m = x % self.radix;
x /= self.radix;
result[used] = std::char::from_digit(m, self.radix).unwrap();
used += 1;
if x == 0 {
break;
}
}
if negative {
write!(f, "-")?;
}
for c in result[..used].iter().rev() {
write!(f, "{}", c)?;
}
Ok(())
}
}
fn main() {
assert_eq!(Radix::new(1234, 10).to_string(), "1234");
assert_eq!(Radix::new(1000, 10).to_string(), "1000");
assert_eq!(Radix::new(0, 10).to_string(), "0");
}
Это все еще можно оптимизировать с помощью:
- создание массива ASCII вместо
char
массива
- инициализация массива без нуля
Поскольку для этих путей требуется unsafe
или внешний ящик типа arraybuf , я их не включал. Вы можете увидеть пример кода в внутренних деталях реализации стандартной библиотеки .