使用具有复杂索引的多维数组是很常见的情况。当所有索引都是整数时,它确实令人困惑且容易出错,因为您可以轻松地混合列和行(或者您拥有的任何内容),并且编译器无法识别问题。实际上应该有两种类型的索引:行和列,但它不在类型级别上表示。
以下是我想要的一个小例子:
var table = new int[RowsCount,ColumnsCount];
Row row = 5;
Column col = 10;
int value = table[row, col];
public void CalcSum(int[,] table, Column col)
{
int sum = 0;
for (Row r = 0; r < table.GetLength(0); r++)
{
sum += table[row, col];
}
return sum;
}
CalcSum(table, col); // OK
CalcSum(table, row); // Compile time error
总结:
有没有办法实现这个目标?完美的解决方案就像typedef
一样,它只用作编译时平面整数的编译时检查。
答案 0 :(得分:1)
x64抖动只会减慢2倍速度。它生成有趣的优化代码。使用struct的循环如下所示:
00000040 mov ecx,1
00000045 nop word ptr [rax+rax+00000000h]
00000050 lea eax,[rcx-1]
s.Idx = j;
00000053 mov dword ptr [rsp+30h],eax
00000057 mov dword ptr [rsp+30h],ecx
0000005b add ecx,2
for (int j = 0; j < 100000000; j++) {
0000005e cmp ecx,5F5E101h
00000064 jl 0000000000000050
这需要一些注释,因为代码不常见。首先,偏移45处的奇怪NOP用于在循环开始时对齐指令。这使得偏移64处的分支更快。 53处的指令看起来完全没必要。你在这里看到的是循环展开,注意5b处的指令如何将循环计数器递增2.然而,优化器不够智能,因此也看不到存储是不必要的。
最重要的是,没有任何ADD指令可供使用。换句话说,代码实际上并不计算“sum”的值。这是因为你没有在循环之后的任何地方使用它,优化器可以看到计算是无用的并完全删除它。
在第二个循环中做得更好:
000000af xor eax,eax
000000b1 add eax,4
for (int j = 0; j < 100000000; j++) {
000000b4 cmp eax,5F5E100h
000000b9 jl 00000000000000B1
现在它完全删除了“sum”计算和“i”变量赋值。它也可以删除整个for()循环但是抖动优化器永远不会这样做,它假定延迟是故意的。
希望现在的信息很明确:避免从人工基准测试中做出假设,并且只能编写真正的代码。您可以通过实际显示“sum”的值使其更真实,以便优化器不会丢弃计算。在循环之后添加以下代码行:
Console.Write("Sum = {0} ", sum);
现在你会发现它已经没有区别了。