首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >即使在范围有限的情况下,‘u32’/‘i32’也是建议的吗?

即使在范围有限的情况下,‘u32’/‘i32’也是建议的吗?
EN

Stack Overflow用户
提问于 2016-10-09 02:29:19
回答 3查看 2K关注 0票数 9

我们应该使用u32/i32还是它的较低的变量(u8/i8u16/i16)来处理范围有限的数目,比如“月中的天数”,从1到30,或者“被试的分数”从0到100?或者为什么我们不应该?

较低的变量(即内存效率)是否有任何优化或好处?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-09 10:40:47

摘要

正确性应优先于性能和正确性(范围为1-100),所有解决方案(u8u32,.)同样糟糕。最好的解决方案是创建一个新类型的,以便从强类型中获益。

我的其余部分试图证明这一说法是正确的,并讨论了创建新类型的不同方法。

更多解释

让我们看一看“主题得分”的例子:唯一的法律价值是0-100。我认为就正确性而言,使用u8u32同样不好:在这两种情况下,变量都可以保存在语义上下文中不合法的值;这是不好的!

认为u8更好,因为它的非法价值较少,这就好比说与熊摔跤比在纽约走动要好,因为你只有一种死亡的可能性(因为熊攻击失血),而不是死亡的许多可能性(车祸、刀子攻击、溺水、.)在纽约。

所以我们想要的是一种保证只保留法律价值的类型。我们想要创建一个新的类型来做到这一点。然而,有多种方式进行,每一种都有不同的优点和缺点。

(A)公开内在价值

代码语言:javascript
运行
复制
struct ScoreOfSubject(pub u8);

Advantage:至少API更容易理解,因为参数已经由类型解释了。更容易理解的是:

  • add_record("peter", 75, 47)
  • add_record("peter", StudentId(75), ScoreOfSubject(47))

我可以说是后一个;-)

Disadvantage:我们实际上不做任何范围检查,非法值仍然可能发生;不好!

(B)使内部值私有,并提供范围检查构造函数

代码语言:javascript
运行
复制
struct ScoreOfSubject(pub u8);

impl ScoreOfSubject {
    pub fn new(value: u8) -> Self {
        assert!(value <= 100);
        ScoreOfSubject(value)
    }
    pub fn get(&self) -> u8 { self.0 }
}

Advantage:我们用很少的代码来执行法律价值,是的:)

使用该类型的Disadvantage:可能会很烦人。几乎每个操作都需要程序员打包和解压这个值。

(C)增加一批实现(除(B)外)

(代码将impl Add<_>impl Display等)

Advantage:程序员可以直接使用该类型并对其执行所有有用的操作--通过范围检查!这是非常理想的。

请看一下马蒂厄M.的评论:

..。通常将分数相乘,或将它们相加,不会产生分数!强输入不仅会强制执行有效值,还会强制执行有效的操作,这样实际上就不会将两个分数除以获得另一个分数。

我认为这是我以前没有说清楚的一个非常重要的问题。强类型可以防止程序员对值(没有任何意义的操作)执行非法操作。一个很好的例子是机箱cgmath,它区分点向量和方向向量,因为两者都支持对它们的不同操作。您可以找到更多的解释here

Disadvantage:大量的代码:(

幸运的是,这个缺点可以通过Rust宏/编译器插件系统来减少。有像newtype_derivebounded_integer这样的板条箱为您进行这种代码生成(免责声明:我从未使用过它们)。

但现在你说:“你不会是认真的吧?我该花时间写新类型的吗?”

不一定,但是如果您正在编写生产代码(==至少有点重要),那么我的回答是:是的,您应该这样做。

票数 9
EN

Stack Overflow用户

发布于 2016-10-09 06:35:57

A无答案的答案:我怀疑你不会看到基准测试有什么不同,除非你做了大量的算术或者处理庞大的数列。

您可能应该只使用更有意义的类型(没有理由使用否定句或一个月中有数百万的上限),并提供所需的方法(例如,不能直接对无符号整数执行abs() )。

票数 4
EN

Stack Overflow用户

发布于 2016-10-09 11:17:04

使用较小的类型可能有很大的好处,但您必须在目标平台上对应用程序进行基准测试才能确定。

第一个也是最容易实现的好处是更好的缓存。不仅您的数据更有可能适合缓存,而且也不太可能丢弃缓存中的其他数据,从而可能改进应用程序的一个完全不同的部分。这是否被触发取决于您的应用程序所访问的内存和顺序。做基准!

使用较小类型的网络数据传输有明显的好处。

较小的数据允许“更大”的指令。128位SIMD单元可以处理4 32位数据或16 8位数据,使某些操作快4倍.在基准测试中,这些指令确实执行速度快了4倍,但整个应用程序的改进不足1%,代码变得更加混乱。使您的程序更好地利用SIMD可能是棘手的。

在有符号/无符号的讨论中,无符号具有稍微好一些的属性,编译器可以或不利用这些属性。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39939386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档