我们应该使用u32
/i32
还是它的较低的变量(u8
/i8
,u16
/i16
)来处理范围有限的数目,比如“月中的天数”,从1到30,或者“被试的分数”从0到100?或者为什么我们不应该?
较低的变量(即内存效率)是否有任何优化或好处?
发布于 2016-10-09 10:40:47
摘要
正确性应优先于性能和正确性(范围为1-100),所有解决方案(u8
,u32
,.)同样糟糕。最好的解决方案是创建一个新类型的,以便从强类型中获益。
我的其余部分试图证明这一说法是正确的,并讨论了创建新类型的不同方法。
更多解释
让我们看一看“主题得分”的例子:唯一的法律价值是0-100。我认为就正确性而言,使用u8
和u32
同样不好:在这两种情况下,变量都可以保存在语义上下文中不合法的值;这是不好的!
认为u8
更好,因为它的非法价值较少,这就好比说与熊摔跤比在纽约走动要好,因为你只有一种死亡的可能性(因为熊攻击失血),而不是死亡的许多可能性(车祸、刀子攻击、溺水、.)在纽约。
所以我们想要的是一种保证只保留法律价值的类型。我们想要创建一个新的类型来做到这一点。然而,有多种方式进行,每一种都有不同的优点和缺点。
(A)公开内在价值
struct ScoreOfSubject(pub u8);
Advantage:至少API更容易理解,因为参数已经由类型解释了。更容易理解的是:
add_record("peter", 75, 47)
或add_record("peter", StudentId(75), ScoreOfSubject(47))
我可以说是后一个;-)
Disadvantage:我们实际上不做任何范围检查,非法值仍然可能发生;不好!
(B)使内部值私有,并提供范围检查构造函数
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_derive
或bounded_integer
这样的板条箱为您进行这种代码生成(免责声明:我从未使用过它们)。
但现在你说:“你不会是认真的吧?我该花时间写新类型的吗?”
不一定,但是如果您正在编写生产代码(==至少有点重要),那么我的回答是:是的,您应该这样做。
发布于 2016-10-09 06:35:57
A无答案的答案:我怀疑你不会看到基准测试有什么不同,除非你做了大量的算术或者处理庞大的数列。
您可能应该只使用更有意义的类型(没有理由使用否定句或一个月中有数百万的上限),并提供所需的方法(例如,不能直接对无符号整数执行abs()
)。
发布于 2016-10-09 11:17:04
使用较小的类型可能有很大的好处,但您必须在目标平台上对应用程序进行基准测试才能确定。
第一个也是最容易实现的好处是更好的缓存。不仅您的数据更有可能适合缓存,而且也不太可能丢弃缓存中的其他数据,从而可能改进应用程序的一个完全不同的部分。这是否被触发取决于您的应用程序所访问的内存和顺序。做基准!
使用较小类型的网络数据传输有明显的好处。
较小的数据允许“更大”的指令。128位SIMD单元可以处理4 32位数据或16 8位数据,使某些操作快4倍.在基准测试中,这些指令确实执行速度快了4倍,但整个应用程序的改进不足1%,代码变得更加混乱。使您的程序更好地利用SIMD可能是棘手的。
在有符号/无符号的讨论中,无符号具有稍微好一些的属性,编译器可以或不利用这些属性。
https://stackoverflow.com/questions/39939386
复制相似问题