为什么我要在 C # 中使用 int 而不是 byte 或 short

关于这个问题,我找到了一些线索。大多数人似乎倾向于在他们的 c # 代码中全面使用 int,即使一个字节或 smallint 将处理数据,除非它是一个移动应用程序。我不明白为什么。将 C # 数据类型定义为与数据存储解决方案中相同的数据类型不是更有意义吗?

我的前提: 如果我使用类型化数据集、 Linq2SQL 类、 POCO,如果我不能保持我的数据类型跨层同步,我会遇到编译器数据类型转换问题。我不太喜欢“系统”。只是因为在 c # 代码中使用 int 更容易,所以要一直进行转换。我总是使用任何最小的数据类型来处理数据库中的数据以及代码中的数据,以保持与数据库的接口清洁。因此,我敢打赌,我的 C # 代码中有75% 使用 byte 或 short,而不是 int,因为这就是数据库中的内容。

可能性: 这是否意味着大多数只在代码中使用 int 的人也会在 sql 存储数据类型中使用 int 数据类型,而不太关心数据库的整体大小,或者他们会在适当的地方在代码中执行 system.Convert?

我关心的原因: 我一直在自己的工作,我只是想熟悉最佳实践和标准的编码约定。

27903 次浏览

大多数情况下,‘不’。

除非你事先知道你要处理的是数以亿计的行,否则这就是一个微观优化。

做最适合域模型的事情。稍后,如果您有性能问题,基准测试和配置文件可以针对它们发生的地方。

如果在任何地方都使用 int,则不需要强制转换或转换。这比使用多个整数大小节省的内存更划算。

这样生活就简单多了。

NET 运行时针对 Int32进行了优化

在性能方面,int 在几乎所有情况下都更快。 CPU 被设计成能够有效地处理32位值。

较短的值很难处理。要读取一个字节,比如说,CPU 必须读取包含它的32位块,然后屏蔽掉上面的24位。

要写入一个字节,它必须读取目标32位块,用所需的字节值覆盖较低的8位,然后再次写回整个32位块。

当然,在空间方面,使用较小的数据类型可以节省几个字节。因此,如果您正在构建一个包含几百万行的表,那么更短的数据类型可能值得考虑。(这可能也是为什么应该在数据库中使用较小的数据类型的好理由)

在正确性方面,int 不容易溢出。如果 好好想想的值只能容纳一个字节,那么在将来的某个时候,对代码进行一些看起来无害的更改意味着将存储更大的值,该怎么办呢?

这就是为什么 int 应该是所有整数数据的默认数据类型的一些原因。如果实际上要存储计算机字节,则仅使用 byte。只有在处理实际指定16位整数值的文件格式或协议或类似文件时才使用 short。如果您只是处理一般的整数,那么将它们设置为 int。

您必须先处理几个 BILLION 行,然后才能对存储容量产生重大影响。假设您有三列,并且不使用字节等效的数据库类型,而使用 int 等效的。

这样每行就有3个(列) x 3个(额外字节) ,或者每行9个字节。

这意味着,对于“几百万行”(假设是三百万行) ,您将额外消耗整整27兆的磁盘空间!幸运的是,我们不再生活在20世纪70年代,你不必担心这个问题:)

如上所述,停止微优化-在转换到/来自不同整数类型的数字类型的性能打击将会比带宽/磁盘空间成本更加困难,除非你正在处理非常,非常,非常大的数据集。

不是我不相信乔恩 · 格兰特和其他人,而是我必须亲眼看看我们的“百万行表”。这张桌子有1018000。我将11个 tinyint 列和6个 smallint 列转换为 int,已经有5个 int 和3个 small datetimes。4个不同的索引使用了不同数据类型的组合,但是很明显,新的索引现在都使用了 int 列。

在没有索引的情况下,进行更改只需要花费40mb 计算基表磁盘使用量。当我将索引添加回来时,整体变化只有30mb 的差异。所以我很惊讶,因为我以为索引的大小会更大。

因此,30mb 值得使用所有不同的数据类型的麻烦,没有办法!我要去 INT 的地盘了,感谢大家把这个肛门保留程序员回到直和快乐的幸福生活没有更多的整数转换... 耶!

我只是迟到了6年,但也许我可以帮助别人。

以下是我会用到的一些指导方针:

  • 如果将来数据可能不适合,那么使用较大的 int 类型。
  • 如果变量被用作 struct/class 字段,那么默认情况下它将被填充以占据整个32位,因此使用 byte/int16不会节省内存。
  • 如果变量是短期的(比如在函数内部) ,那么较小的数据类型不会有太大的帮助。
  • “ byte”或“ char”有时可以更好地描述数据,并可以进行编译时检查,以确保不会意外地赋给它较大的值。例如:。如果使用一个字节存储一个月的日期(1-31) ,并尝试为其分配1000,那么它将导致一个错误。
  • 如果变量在大约100个或更多的数组中使用,我会使用较小的数据类型,只要它有意义。
  • Byte 和 int16数组不像 int (原语)那样线程安全。

没有人提到的一个话题是有限的 CPU 缓存。较小的程序比较大的程序执行得更快,因为 CPU 可以在更快的 L1/L2/L3缓存中容纳更多的程序。

使用 int 类型可以减少 CPU 指令,但是它也会迫使更高比例的数据内存不适合 CPU 缓存。指令执行起来很便宜。现代的 CPU 内核每个时钟周期可以执行3-7条指令,但是一个缓存错过另一方面可能会花费1000-2000个时钟周期,因为它必须去所有的方式内存。

当内存保守时,它也会导致应用程序的其余部分表现得更好,因为它没有被挤出缓存。

我使用一个字节数组和一个 int 数组以随机顺序访问随机数据,进行了一个快速求和测试。

const int SIZE = 10000000, LOOPS = 80000;
byte[] array = Enumerable.Repeat(0, SIZE).Select(i => (byte)r.Next(10)).ToArray();
int[] visitOrder = Enumerable.Repeat(0, LOOPS).Select(i => r.Next(SIZE)).ToArray();


System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
int sum = 0;
foreach (int v in visitOrder)
sum += array[v];
sw.Stop();

下面是及时的结果(勾选) : (x86,发布模式,不带调试器,. NET 4.5,I7-3930k)(越小越好)

________________ Array Size __________________
10  100   1K   10K  100K    1M   10M
byte: 549  559  552   552   568   632  3041
int : 549  566  552   562   590  1803  4206
  • 在我的 CPU 上使用字节随机访问1M 个项目,性能提高了285% !
  • 10000以下的东西几乎看不出来。
  • 在这个基本的求和测试中,int 从来没有比 byte 快过。
  • 这些值将随具有不同缓存大小的不同 CPU 而变化。

最后一点,有时候我看到现在的开源。NET 框架,看看微软的专家做什么。那个。NET 框架使用 byte/int16的次数少得惊人。我实际上找不到。