为什么我应该使用int而不是一个字节或C#中的短

关于这个问题,我find了几条线索。 大多数人似乎赞成在他们的c#代码中使用int,即使一个字节或smallint会处理数据,除非它是一个移动应用程序。 我不明白为什么。 将C#数据types定义为数据存储解决scheme中的相同数据types是否更有意义?

我的前提:如果我正在使用types化的数据集,Linq2SQL类,POCO,这种或那种方式,我会遇到编译器数据types转换问题,如果我不保持我的数据types跨我的层同步。 我真的不喜欢做System.Convert,因为在c#代码中使用int更容易。 我总是使用任何最小的数据types来处理数据库中的数据以及代码,以保持我的数据库接口干净。 所以,我敢打赌,我的C#代码中的75%是使用字节或短而不是int,因为这是数据库中的内容。

可能性:这是否意味着大多数在代码中使用int的大多数人也使用int数据types作为它们的sql存储数据types,并且可能不关心数据库的整体大小,还是在代码中执行system.convert?

为什么我在乎:我一直在自己的工作,我只是想熟悉最佳实践和标准的编码惯例。

在性能方面,几乎所有情况下int都更快。 CPU被devise为可以有效地使用32位值。

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

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

空间方面,当然,通过使用较小的数据types可以节省几个字节。 所以如果你正在build立一个有几百万行的表,那么较短的数据types可能是值得考虑的。 (同样可能是你的数据库中使用较小数据types的一个很好的理由)

正确的说,一个int不容易溢出。 如果你认为你的价值将在一个字节内适合,那么在将来的某个时刻,对代码的一些无害的改变意味着更大的值被存储在它里面呢?

这些是int为所有整型数据的默认数据types的一些原因。 如果你真的想存储机器字节,只能使用字节。 只有在处理文件格式或协议或类似的实际指定16位整数值的情况下才使用短裤。 如果你只是在处理整数,使他们整数。

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

以下是我将使用的一些准则:

  • 如果有可能数据将来不适合然后使用较大的inttypes。
  • 如果variables被用作struct / class字段,那么默认情况下它将被填充以占用整个32位,所以使用byte / int16将不会节省内存。
  • 如果variables是短暂的(就像在一个函数内),那么较小的数据types将不会有多大帮助。
  • “字节”或“字符”有时可以更好地描述数据,并且可以进行编译时检查,以确保事故时不会分配较大的值。 例如,如果使用一个字节存储月份的date(1-31),并尝试将1000分配给它,则会导致错误。
  • 如果variables用于大约100或更多的数组,我会使用更小的数据types,只要有意义。
  • byte和int16数组并不像int(一个原语)那样安全。

没有人提出的一个主题是有限的CPUcaching。 较小的程序执行速度较快,而较大的程序执行速度较快,因为CPU可以在较快的L1 / L2 / L3高速caching中容纳更多的程序。

使用inttypes可能导致更less的CPU指令,但是它也会强制更高百分比的数据存储器不适合CPU高速caching。 指令执行起来很便宜。 现代CPU内核可以在每个时钟周期内执行3-7条指令,但另一方面,单个caching未命中可能需要1000-2000个时钟周期,因为它必须一直到RAM。

当内存保存时,也会导致应用程序的其余部分执行得更好,因为它不会被挤出caching。

我做了一个快速的总和testing,使用一个字节数组和一个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(); 

下面是时间的结果(ticks):(x86,release mode,without debugger,.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%!
  • 任何10,000以下的东西都不是很明显。
  • 对于这个基本的总和testing,int不会更快。
  • 这些值将与具有不同高速caching大小的不同CPU一起使用。

最后一点需要注意的是,有时候我会看看现在开源的.NET框架,看看微软的专家在做什么。 .NET框架使用byte / int16令人惊讶的less。 我实际上找不到任何东西。

在存储容量方面存在显着差异之前,您必须处理几十亿行。 比方说,你有三列,而不是使用一个字节等价的数据库types,你使用一个int等价物。

这给了我们每行3(列)x 3(额外的字节),或每行9个字节。

这意味着,对于“几百万行”(可以说三百万),你正在消耗整个额外的27兆字节的磁盘空间! 幸运的是,当我们不再生活在20世纪70年代,你不应该担心这个:)

如上所述,停止微观优化 – 转换到/从不同的整数types的数字types中的性能打击会比你带来的要多得多,比带宽/磁盘空间成本要困难得多,除非你处理的是非常非常非常大数据集。

大多数情况下,“否”。

除非你事先知道你将要处理数百万行,这是一个微观优化。

做最合适的域模型。 后来,如果你有性能问题,基准和configuration文件来指出它们发生的地方。

不是说我不相信乔恩·格兰特和其他人,但我必须亲眼看看我们的“百万行桌”。 桌子有108.8万。 我将11个tinyint列和6个smallint列转换为int,已经有5个int&3个小时间。 4个不同的索引使用了各种数据types的组合,但显然新索引现在都使用int列。

进行更改只会花费我40 MB计算基本磁盘使用情况而无索引。 当我添加索引时,整体变化总体上只有30 MB差异。 所以我很惊讶,因为我认为指数的规模会更大。

所以30 MB值得使用所有不同的数据types的麻烦,不! 我去INT土地,谢谢大家设置这个肛门保留程序员回到直线和幸福的生活没有更多的整数转换… yippeee!

如果在任何地方都使用int,则不需要转换或转换。 这比通过使用多个整数大小保存的内存大得多。

它只是使生活更简单。

.NET运行时为Int32进行了优化。 看看以前的讨论在.NET整数与Int16?