我只迟了6年,但也许我可以帮助别人。
这是我会使用的一些准则:
- 如果有可能将来无法容纳该数据,请使用较大的int类型。
- 如果将该变量用作struct / class字段,则默认情况下将对其进行填充以占用整个32位,因此使用byte / int16将不会节省内存。
- 如果变量寿命很短,那么(就像在函数内部一样),较小的数据类型将无济于事。
- 有时,“字节”或“字符”可以更好地描述数据,并且可以进行编译时间检查以确保在意外情况下不会为其分配较大的值。例如,如果使用字节存储月份中的一天(1-31)并尝试为其分配1000,则将导致错误。
- 如果在大约100或更多的数组中使用变量,则我会使用较小的数据类型,只要它有意义。
- byte和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();
以下是时间(滴答声)的结果:(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%!
- 少于10,000的东西几乎不被注意到。
- 对于这个基本的总和测试,int从未比字节快。
- 这些值将随具有不同缓存大小的CPU的不同而变化。
最后一点,有时我看一下现在开放源代码的.NET框架,以了解Microsoft的专家所做的事情。.NET框架很少使用byte / int16。我实际上找不到任何东西。