#byte #duration #convert-bytes #convert #format #throughput

human-repr

生成字节、持续时间甚至吞吐量的美丽的人类可读表示!

21个版本 (3个稳定版)

1.1.0 2023年4月19日
1.0.1 2022年7月27日
0.11.0 2022年7月23日

#37 in 值格式化

Download history 3348/week @ 2024-04-22 3544/week @ 2024-04-29 3475/week @ 2024-05-06 3431/week @ 2024-05-13 2889/week @ 2024-05-20 2283/week @ 2024-05-27 2897/week @ 2024-06-03 2211/week @ 2024-06-10 2516/week @ 2024-06-17 2377/week @ 2024-06-24 2402/week @ 2024-07-01 2395/week @ 2024-07-08 3253/week @ 2024-07-15 2057/week @ 2024-07-22 2279/week @ 2024-07-29 2383/week @ 2024-08-05

10,074 每月下载量
14 个Crates中(10个直接) 使用

MIT 许可证

37KB
576

human-repr

Crates.io Docs dependency status Crates.io GitHub Sponsors

生成字节、持续时间甚至吞吐量的美丽的人类可读表示!

简介

这个crate提供了一套完整的

  • 计数功能,默认支持SI前缀:kMGTPEZY,包括可选的IEC前缀和“混合”前缀(见Rust特性)。
  • 持续时间,支持SI前缀nsµsms用于亚秒值,还包括一些自定义格式,如M:SS.s(分钟:秒,保留1位小数)和H:MM:SS(小时:分钟:秒)用于大于60秒的值。
  • 吞吐量,支持SI接受的/d/h/min/s,当为每秒时,它甚至得到SI前缀,这是最快的。

此外,这个crate没有任何依赖项,经过良好的测试,并且非常快,生成表示的时间不到50ns!通过criterion基准测试验证。

它们与任何Rust原始数字以及Duration一起工作!

// counts (bytes, bare, or any custom unit).
use human_repr::HumanCount;
assert_eq!("43.21GB", 43214321123_u64.human_count_bytes());
assert_eq!("74.9M", 74893200.human_count_bare());
assert_eq!("540.5kPackets", 540464_u32.human_count("Packets"));
assert_eq!("48.1°C", 48.132323432.human_count("°C"));
assert_eq!("123k🦀", 123e3.human_count("🦀"));

// durations with primitives.
use human_repr::HumanDuration;
assert_eq!("1.8ns", 0.0000000018.human_duration());
assert_eq!("15.6µs", 0.0000156.human_duration());
assert_eq!("10ms", 0.01.human_duration());
assert_eq!("3.44s", 3.435999.human_duration());
assert_eq!("19:20.4", 1160.36.human_duration());
assert_eq!("1:14:48", 4488u16.human_duration());

// durations with std's Duration.
use std::time::Duration;
assert_eq!("15.6µs", Duration::from_nanos(15_600).human_duration());
assert_eq!("10ms", Duration::from_secs_f64(0.01).human_duration());
assert_eq!("1:14:48", Duration::new(4488, 395_000_000).human_duration());

// throughputs (bytes, bare, or any custom unit).
use human_repr::HumanThroughput;
assert_eq!("1.2MB/s", 1248632.human_throughput_bytes());
assert_eq!("9/d", 0.000104166666667.human_throughput_bare());
assert_eq!("6.1tests/min", 0.101265.human_throughput("tests"));
assert_eq!("54°C/h", 0.015.human_throughput("°C"));
assert_eq!("123M⭐/s", 123e6.human_throughput(""));

📌 1.1系列的新增功能

这个版本主要

  • 包括一个用于serde的可选功能;
  • 使用 Cow 来代替泛型单位(可能更优化的二进制);
  • 将吞吐量中的分钟符号从 m 改为 min(这似乎是实际接受的SI符号)。
    同时完善了所有细节。
1.0 系列新特性

此crate升级到1.0!🎉 达到这一步有很多改进...

从1.0版本开始,移除了 HumanRepr 特性。现在有单独的特性用于每个概念。
我意识到单独的特性更灵活,所以我只在实际需要的地方实现它们,同时可以独立地进行演变。
特性名称也变得更简单:HumanCount、HumanDuration和HumanThroughput。

0.11系列新特性

从版本0.11开始,为 &strPartialEq 实现不会分配任何字符串!
我开发了一个特别有趣的 Write 实现,它将部分序列与 Display 实现将生成的内容进行比较!非常有意思

0.10系列新特性

从版本0.10开始,Debug 实现将显示原始值和最终表示!非常酷

# use human_repr::{HumanDuration, HumanThroughput};
assert_eq!("HumanDuration { val: 1.56e-5 } -> 15.6µs", format!("{:?}", 0.0000156.human_duration()));
assert_eq!(r#"HumanThroughput { val: 0.015, unit: "°C" } -> 54°C/h"#, format!("{:?}", 0.015.human_throughput("°C")));
0.4系列新特性

从版本0.4开始,生成输出时不再分配任何字符串!我返回了实现了 Display 的结构体,所以你可以打印它们而无需进行堆分配!如果你确实需要字符串,只需简单的 .to_string() 即可。

如何使用它

将此依赖项添加到你的Cargo.toml文件

human-repr = "1"

然后只需使用所需的特性!

use human_repr::{HumanCount, HumanDuration, HumanThroughput};

3000_u16.human_count("bytes");
(-5i8).human_count_bytes();

4244.32_f32.human_duration();
0.000000000004432_f64.human_duration();
# use std::time::Duration;
Duration::from_secs_f64(0.00432).human_duration();

8987_isize.human_throughput("transactions");
93321_usize.human_throughput_bytes();

它们适用于所有Rust原生数字类型:u8u16u32u64u128usizef32f64i8i16i32i64i128isize,以及 Duration 类型。

请注意,stdDuration 提供了类似的 Debug 实现功能,但它并不太 人性

# use human_repr::HumanDuration;
# use std::time::Duration;
let default = format!("{:?}", Duration::new(0, 14184293));
assert_eq!("14.184293ms", default); // 😫👎
assert_eq!("14.2ms", Duration::new(0, 14184293).human_duration()); // 😃👍

当然,我还提供了它没有的分钟和小时视图...

# use human_repr::HumanDuration;
# use std::time::Duration;
let default = format!("{:?}", Duration::new(10000, 1));
assert_eq!("10000.000000001s", default); // 😫👎
assert_eq!("2:46:40", Duration::new(10000, 1).human_duration()); // 😃👍

某些方法提供的 unit 参数意味着你正在处理的实体,例如“字节”、“任务”、“它”、“°C”、“🍎”,等等。
字节(作为“B”)和裸单位有专门的方法供你方便使用。

Rust功能

根据SI标准,千字节中有1000字节。
还有一个标准称为 IEC,其中1 kibibyte 包含1024个字节,但这个标准仅适用于测量那些自然是以2为幂的量,例如内存条。在主要操作系统中的文件大小也正在改为使用1000的除数。

注意不要使用SI前缀来表示IEC量,这将是不正确的。
但我仍然支持它,如果你真的想的话 ;)

默认情况下,human-repr 使用SI前缀,1000 除数,并且在前缀/单位之间没有空格。

该库支持以下可选特性

  • space => 在值和前缀/单位之间包含空格:48 B 而不是 48B15.6 µs 而不是 15.6µs,以及 12.4 kB/s 而不是 12.4kB/s;
  • iec => 使用IEC前缀而不是SI前缀:KiMiGiTiPiEiZiYi(意味着 1024);
  • 1024 => 使用 1024 除数,无论 iec 是否启用(即SI模式),小写 k 转换为大写 'K'
  • serde => 启用序列化和反序列化支持。

人类持续时间魔咒

在设计人类持续时间行为时,我只使用了一个关键概念:清晰性。

3.44s 比比 3.43584783784s 更有意义,而 14.1µs 比比 .0000141233333s 要好得多。

所以,我所做的就是:将值四舍五入到最多两位小数(较大值有更多小数位),并找到表示它们的最佳前缀,最小化输出值小于 1。最佳前缀的搜索甚至考虑了应用四舍五入后的结果!

0.000999999 并不会变成 999.9µs(截断)或 1000µs(不良前缀),它将自动升级到下一个 1ms

人类持续时间前缀无缝地从纳秒变化到小时!

  • 小于60秒的值以 SS[.ss]前缀 的形式呈现,最多两位小数;
  • 从1分钟开始,它变为 M:SS[.s]
  • 从1小时开始,它变为 H:MM:SS
  • .0.00 从输出中移除,而不是生成它们,这是在算法中直接处理的。

人类的吞吐量魔法

我使用类似的逻辑来计算人类的吞吐量。人类的大脑对“吞吐量”这个词是多么的难以理解!
如果处理 123 个项目花费了 1165263 秒,那么它的速度有多快?这并不明显...

即使我们将持续时间除以项目数量,帮助也不是很大:9473 秒/项目仍然看起来不太好。有多快?我们无法确定。

嗯,我们每单位时间完成了多少个项目?
哦,我们只需要取倒数,所以是 0.000105555569858 项目/秒,这就是答案! 😂

为了使其更有意义,我们需要将其乘以 3600(一小时中的秒数),以获得每小时 0.38,这要好得多,然后再乘以 24(一天中的小时数),最终得到每天 9.12!现在我们知道这个过程有多快了! \o/

正如你所见,对我们的大脑来说,估计这一点并不容易...

人类的吞吐量前缀无缝地从每秒转换为每天!

  • 和持续时间魔法一样,.0.00 也不会被高效生成;
  • 当处于最快的单位(每秒)时,它还会自动插入 SI 前缀,因此我们得到 2.4MB/s6.42Gitems/s 👍

人类计数魔法

这是其中最简单的一个,我只是不断地除以当前的除数(1000 或 1024),直到值小于那个值。完全没有使用对数或指数的奇怪业务。

四舍五入也得到了处理,因此没有截断或不良前缀,小数位数也随着前缀的增大而增加,而 .0.00 也永远不会生成。

变更日志亮点

  • 1.1.x 2023 年 4 月 19 日:为 serde 新增了可选功能,使用 Cow 而不是泛型为单位,将吞吐量中分钟的符号从 m 更改为 min,整体优化
  • 1.0.x 2022 年 7 月 26 日:删除了 HumanRepr trait,现在有针对每个概念的单独 trait:HumanCountHumanDurationHumanThroughput
  • 0.11.x 2022 年 7 月 22 日:为 &str 新增了 PartialEq 实现,这甚至更快,并且不分配任何字符串
  • 0.10.x 2022 年 7 月 17 日:添加了带有原始值和渲染值的 Debug 实现,添加了新的“裸单位”方法变体,从默认功能中删除 space
  • 0.9.x 2022 年 6 月 22 日:不要在格式字符串中使用捕获的标识符,以支持更广泛的 Rust 版本,而不是仅支持 >= 1.58
  • 0.8.x 2022 年 6 月 12 日:将 nospace 功能更改为 space,以避免负逻辑(现在是默认值,以保持行为)
  • 0.7.x 2022 年 6 月 4 日:通过新的 trait HumanReprDuration 支持 std::time::Duration,在分钟表示中包含一个小数位
  • 0.6.x 2022 年 6 月 4 日:使用新的 ops::Neg 实现,提高了对有符号数的支持
  • 0.5.x 2022 年 6 月 3 日:添加了分钟表示 M:SS,介于秒和完整的 H:MM:SS 之间
  • 0.4.x 2022年6月3日:通过Display引入新的渲染引擎,速度更快且不分配任何字符串
  • 0.3.x 2022年6月1日:仅支持一组新的前缀,用于1024(不包含iec
  • 0.2.x 2022年6月1日:更灵活的API(impl AsRef<str>),大幅改进了文档
  • 0.1.x 2022年6月1日:首次发布,包括readme、方法和模块文档,描述已实现的功能

许可证

本软件受MIT许可证的许可。完整的许可证文本请参阅顶级分发目录中的LICENSE文件。


维护开源项目很困难且耗时,我已经为此投入了大量的❤️和努力。

如果您欣赏我的工作,可以通过捐赠来支持我!谢谢 😊

Donate with PayPal button


依赖项

~170KB