我为什么要使用int,而不是一个字节或短于C#

问题描述 投票:57回答:7

我在关于这个问题找到了几个线程。大多数人似乎使用int类型的C#代码翻过主板即使一个字节或SMALLINT将处理数据,除非它是一个移动应用程序青睐。我不明白为什么。难道不是更有意义来定义你的C#的数据类型为相同的数据类型,这将是您的数据存储解决方案?

我的前提:如果我使用的是强类型DataSet,LINQ2SQL类,POCO,这种或那种方式,我会碰到编译器的数据类型转换的问题,如果我不把我的数据类型同步在我的层次。我真的不喜欢做System.Convert只因为它是更容易在C#代码INT使用翻过板上的所有时间。我一直使用的任何需要的最小数据类型来处理数据库,以及在代码中的数据,我的界面保持到数据库干净。所以,我敢打赌我的C#代码75%是用字节或而不是为int短,因为这是在数据库中。

可能性:这是否意味着谁只是在代码中使用int的一切大多数人还用int数据类型为他们的SQL存储的数据类型和并不十分关心他们的数据库的整体大小,或做他们做system.convert代码(如适用)?

为什么我关心:我对我自己永远工作,我只是想熟悉最佳做法和标准编码约定。

c# asp.net sql-server types
7个回答
81
投票

性能方面,一个int是在几乎所有情况下更快。所述CPU被设计成与32位值有效地工作。

较短的值是复杂的处理。读取单个字节,比方说,CPU必须读取包含它的32位的块,然后屏蔽掉的高24位。

写一个字节,它有读出目的地的32位块,将具有所需字节值覆盖的低8位,并再次返回写入整个32位的块。

空间的角度来看,当然,你通过使用更小的数据类型节省几个字节。所以,如果你正在构建一张桌子几百万行,再短的数据类型可能是值得考虑的。 (而同样可能是很好的理由,为什么你应该在你的数据库中使用更小的数据类型)

和正确性的角度来看,一个int不容易溢出。如果你认为你的价值是要适应一个字节中,然后在未来的代码一些看似无害的变化意味着更大的值存储到它的一些问题?

这些都是一些原因INT应该是所有积分数据的默认数据类型。只有当你真正要存储机器字节使用字节。只有用短裤,如果你正在处理的文件格式或协议或类似,实际上指定的16位整数。如果你只是应付一般的整数,让他们整数。


20
投票

我6年时间只晚,但也许我可以帮助别人。

这里有一些指引,我会用:

  • 如果数据不适合在未来有可能再使用较大的int类型。
  • 如果变量被用作一个结构/类字段然后默认情况下它会被填充,以便使用字节/ INT16不会节省内存占用整个32位反正。
  • 如果变量短暂的,然后(如函数内),那么较小的数据类型不会有太大的帮助。
  • “字节”或“炭”有时可以描述数据好,可以做编译时检查,以确保更大的数值没有分配给它的事故。例如如果使用一个字节存储的月份(1-31)的一天,尝试分配1000到它,然后它会导致错误。
  • 如果变量中的约100或只要它是有意义更我会使用更小的数据类型的阵列使用。
  • 字节和INT16数组不是作为线程安全作为int(基本)。

没有人提出了一个话题是有限的CPU缓存。较小的程序来执行更快然后较大的,因为CPU可以在较快的L1 / L2 / L3高速缓存适合更多的程序。

使用int类型可以导致更少的CPU指令但是它也将迫使数据存储的高百分比不适合在CPU缓存。说明很便宜执行。现代的CPU内核可以每个时钟周期执行的指令3-7然而,从另一方面单一的高速缓存未命中可以花费1000-2000个时钟周期,因为它必须全力以赴,以RAM的方式。

当内存保守这也导致在执行应用程序的其他部分更好,因为它不挤掉缓存。

我做了快速和检验与在同时使用一个字节数组,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();

以下是时间的结果(蜱):(86,发行方式,无需调试,.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
  • 访问100万件随机我的CPU使用的字节有性能提升285%!
  • 低于10,000的事情是难以察觉。
  • INT从来没有那么快字节为这个基本和检验。
  • 这些值将用不同的缓存大小不同的CPU而有所不同。

最后要说明的,有时候,我看现在的开源.NET架构,看看微软的专家们。 .NET框架使用字节/ INT16少得惊人。我找不到任何实际。


8
投票

你将不得不处理数十亿行,这使得在存储容量方面的任何显著差异前。比方说你有三列,而不是使用一个字节相当于数据库类型,您使用int当量。

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

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

正如上面所说的,停止微型优化 - 对性能的影响在不同类似于整数数值类型转换成/会打你多少,比带宽/磁盘空间的成本更难,除非你是在处理非常,非常,非常大数据集。


7
投票

在大多数情况下,“否”。

除非你知道前期,你将要处理的数百万行的100的,这是一个微型优化。

做最适合的领域模型。以后,如果您有性能问题,基准测试和配置文件以针点,他们的存在的。


5
投票

这并不是说我不相信乔恩·格兰特和其他人,但我必须亲眼看看我们的“百万行的表”。该表有1018000。我转换11 TINYINT列和6列SMALLINT转换成int,已经有5 INT&3个smalldatetimes。 4个不同的索引使用的各种数据类型的组合,但显然新指标目前都在使用INT列。

作出更改只花了我40 MB的计算没有索引基表的磁盘使用情况。当我在总体变化添加的指标后面只有30 MB的总体差异。所以,我很惊讶,因为我认为索引大小将更大。

那么,30 MB值得使用所有不同的数据类型,没办法的麻烦!我关到INT土地,感谢大家设置此肛门固程序员回来没有更多的整数转换的直线和快乐幸福的生活...... yippeee!


4
投票

如果INT到处使用,不需要铸造或转换。这是降压比的内存,您将使用多个整数尺寸节省更大的爆炸。

它只是让生活更简单。


4
投票

.NET运行时针对的Int32优化。看到.NET Integer vs Int16?前面的讨论

© www.soinside.com 2019 - 2024. All rights reserved.