[英]Typedef for indexes in C# with static type checking without runtime overhead
使用具有复杂索引的多维数组是很常见的情况。 当所有索引都是整数时,这真的很容易混淆,并且容易出错,因为您可以轻松地混合列和行(或您所拥有的任何东西),并且编译器无法识别问题。 实际上,应该有两种类型的索引:行和列,但是它不是在类型级别上表示的。
这是我想要的一个小例子:
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
这样的东西,它仅用作编译时检查以编译为平面int。
x64抖动只会使速度减慢2倍。 它生成有趣的优化代码。 使用该结构的循环如下所示:
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
现在,它完全删除了“求和”计算和“ i”变量分配。 它也可能删除了整个for()循环,但是抖动优化器从未做到这一点,它假设延迟是有意的。
希望到目前为止,信息已经清楚了:避免根据人工基准进行假设,并且只能描述真实的代码。 您可以通过实际显示“ sum”的值来使其更真实,这样优化器就不会丢弃计算。 在循环之后添加以下代码行:
Console.Write("Sum = {0} ", sum);
现在,您将看到没有任何区别了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.