我应该使用byte还是int?

40

我记得曾经在某处阅读过使用Int32比Byte更好(在性能方面),即使你只需要Byte。这仅适用于您不关心存储的情况。这个观点是否正确?

例如,我需要一个变量来保存一周的某一天。我应该使用哪种类型?

int dayOfWeek;
或者
byte dayOfWeek;

编辑: 各位,我知道 DayOfWeek 枚举。这个问题是关于其他事情的。


1
对于那个特定的例子,我不会使用 int 或 byte。在这种情况下,枚举类型会更好(2 是什么意思?星期二?星期一?)。我知道你是在概括,但有些特定情况可能需要使用其他严格数值类型以外的东西来处理。 - Michael Todd
2
就效率而言,如果没有进行性能分析,你是无法真正了解的。如果你不进行性能分析,那么你就无法进行优化。 - kyoryu
6个回答

25

通常情况下,是的,32位整数性能稍微好一些,因为它已经适当地对齐了本地CPU指令。只有在你实际需要存储该大小的内容时,才应该使用更小的数字类型。


3
“store” 的意思是指存储在数据库或文件中? - niaher
3
好的。如果您正在与一个期望一小块字节数数据的本地应用程序进行交互,则也可以这样做。 - MikeP
2
如果它们在一个消耗过多内存的大数组中,使用字节而不是整数仍然可以是一个不错的选择。 - Ponkadoodle
没错。你选择它是出于内存原因,而不是性能原因。 - MikeP
7
“Store”指的是在内存中储存。项目以字节序列的形式存储在文件中,因此如果您担心磁盘空间,应使用字节。项目由CPU以32位或64位整数处理(取决于您的处理器),因此任何小于该数量的项目都将被“升级”为32位或64位表示,以供运行时计算。 - Jake
1
在BCL中,二进制数据更常以byte[](八位字节数组)而非int[]uint[]的形式给出,因此在这种情况下byte似乎更受青睐。当然,如果使用int[],则限制了数据长度为32位的整数倍数的情况(而不是8位),这可能会根据上下文成为问题或优势。 - Jeppe Stig Nielsen

11

除非有强烈的理由不这样做,否则应该使用DayOfWeek枚举。

DayOfWeek day = DayOfWeek.Friday;

为了解释一下我被踩的原因:

你的代码正确性几乎总是比性能更重要,特别是在我们谈论这么小的差异时。如果使用枚举或类来表示数据的语义(无论是DayOfWeek枚举还是其他枚举,或者Gallons或Feet类),可以使你的代码更清晰、更易于维护,这将帮助你安全地进行优化。

int z;
int x = 3;
int y = 4;
z = x + y;

这可能会编译通过。但是无法确定它是否有意义。

Gallons z;
Gallons x = new Gallons(3);
Feet y = new Feet(4);
z = x + y;

这段代码无法通过编译,甚至看起来很明显为什么会出错——把加仑和英尺加在一起没有任何意义


3
是的。我相信你用它来测量苹果金橘的体积。 - kyoryu
2
同意。误解变量代表的含义可能比内存或磁盘空间限制造成的错误更多! - Nij

7
我的默认立场是尽可能使用强类型来添加对值的约束 - 在您事先知道这些值的情况下。因此,在您的示例中,使用byte dayOfWeek可能更可取,因为它更接近您期望的值范围。
以下是我的推理; 以存储和传递日期的年份部分为例。考虑到包括SQL Server DateTimes在内的系统的其他部分时,年份部分受限于1753年至9999年(请注意,C#DateTime的可能范围不同!)因此,short覆盖了我的可能值,如果我尝试传递任何较大的值,编译器将在代码编译之前警告我。不幸的是,在这个特定的例子中,C# DateTime.Year属性将返回一个int - 因此,如果我需要将例如DateTime.Now.Year传递给我的函数,那么我必须转换结果。
这个起始位置是由长期存储数据的考虑驱动的,假设有“数百万行”和磁盘空间 - 即使它很便宜(当您托管并运行SAN或类似设备时,它就不那么便宜了)。
在另一个DB示例中,我会使用更小的类型,例如byte(SQL Server tinyint)用于查找ID,因为我确信不会有很多查找类型,而对于可能有更多记录的id,则使用long(SQL Server bigint)。即用于事务记录。
因此,我的经验法则是:
1.如果可能,请首先选择正确性。在您的示例中使用DayOfWeek,当然:) 2.选择适当大小的类型,从而利用编译器安全检查,在最早可能的时间给您错误; 3.但是,要抵消极端的性能需求和简单性,特别是在不涉及长期存储或考虑查找(低行数)表而不是事务性(高行数)表时。
为了清晰起见,DB存储往往不会像您预期的那样快速缩小,从bigint到较小的类型。这既是由于填充到字边界和DB内部页面大小问题。但是,您可能会将每个数据项存储多次在您的DB中,例如通过存储随着时间变化的历史记录,并保留最近几天的备份和日志备份。因此,节省几个百分点的存储需求将在存储成本方面带来长期的节省。
我个人从未遇到过字节与整数的内存性能成为问题的情况,但我已经浪费了数小时的时间来重新分配磁盘空间,并且由于没有一个人可以监视和管理这些事情,导致了活动服务器完全停滞的情况。

+1 是为了真正发挥强类型的作用。强类型的最大好处并不是 IntelliSense! - kyoryu

5
使用int。计算机内存由"字"寻址,通常每个字长为4个字节。这意味着,如果您想从内存中获取一个字节的数据,CPU必须从RAM检索整个4字节的单词,并执行一些额外的步骤来隔离您感兴趣的单个字节。在考虑性能时,对于CPU来说,检索整个字并完成它将更容易。
实际上,在性能方面,您不会注意到两者之间有任何差异(除了在极端情况下是稀有的)。这就是为什么我喜欢使用int而不是byte,因为您可以存储更大的数字,几乎没有任何惩罚。

如果性能不会受到太大影响,那么我更喜欢坚持语义,并在只需要一个字节的地方使用字节。这样我就可以避免一些意外的错误。 - niaher
2
实际上,CPU必须从RAM中检索整个高速缓存行,然后从缓存中提取四字节的单词,最后提取所需的字节。 - rpetrich

4

在存储量方面,使用byte,在CPU性能方面,使用int


所以 byte 就像其他整数一样工作?基本上是这样的。https://en.wikipedia.org/wiki/Integer_(computer_science)#Common_integral_data_types - carloswm85

2

System.DayOfWeek

MSDN

通常使用int,不是为了性能而是为了简单。


1
是的,我知道。DayOfWeek 变量只是一个例子。 - niaher
1
@niaher - 记住,我们程序员是非常字面意义的人。 - ChaosPandion
1
这个获得了赞?现在它说的完全不同了。混乱统治着。 - Robert Harvey
5
即使这是个例子,这也是一个很好的观点。除非你真的要存储的是int或byte类型数据,否则不要使用它们。使用一个能够封装你所做操作语义的数据类型。这可以防止错误,如将加仑与英尺相加。正确性在90%以上的情况下比效率更重要,而正确性可以让你更快地进行优化。 - kyoryu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接