Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中索引的Typedef,带有静态类型检查,无运行时开销_C#_Typechecking_Static Typing - Fatal编程技术网

C#中索引的Typedef,带有静态类型检查,无运行时开销

C#中索引的Typedef,带有静态类型检查,无运行时开销,c#,typechecking,static-typing,C#,Typechecking,Static Typing,使用具有复杂索引的多维数组是非常常见的情况。当所有索引都是int时,这真的很容易混淆和出错,因为您可以很容易地混淆列和行(或任何您拥有的),并且编译器无法识别问题。实际上,应该有两种类型的索引:行和列,但它不是在类型级别上表示的 下面是我想要的一个小例子: var table = new int[RowsCount,ColumnsCount]; Row row = 5; Column col = 10; int value = table[row, col]; public void Calc

使用具有复杂索引的多维数组是非常常见的情况。当所有索引都是int时,这真的很容易混淆和出错,因为您可以很容易地混淆列和行(或任何您拥有的),并且编译器无法识别问题。实际上,应该有两种类型的索引:行和列,但它不是在类型级别上表示的

下面是我想要的一个小例子:

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
var table=newint[rowsunt,columnsunt];
行=5;
列col=10;
int值=表[行,列];
公共void CalcSum(int[,]表,列col)
{
整数和=0;
for(行r=0;r
总结:

  • 应静态检查索引是否混淆(类型检查)
  • 重要它们应该具有运行时效率,因为将整数包装到包含索引的自定义对象,然后再将其展开,对性能来说是不好的
  • 它们应该隐式转换为int,以便在本机多维数组中用作索引

有没有办法做到这一点?完美的解决方案是类似于
typedef
的东西,它充当编译时检查功能,仅编译为平面整数。

使用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 

现在您将看到不再有任何区别。

如果两种类型都隐式转换为整数,编译器如何知道它是错误的?它将推断出其中任何一个是正确的。将其包装到
结构中有什么错?即使隐式转换为int方法调用参数,也可以执行类型检查。在结构中包装的速度比int慢2倍(我刚刚用一个合成测试进行了检查)。你的测试是什么样子的?这里是:怪异。。我从你的测试中得到了几乎相同的速度。2319ms->int,2347ms->struct.Good catch,missing Console.Write(“Sum={0}”,Sum)是一个愚蠢的错误。
现在,你会发现它们已经没有区别了。
确实有。557毫秒对445毫秒-速度降低25%。我不打算追逐“25%=2倍减速”的说法。让你的情况与微软,唯一可以真正改变抖动。在connect.microsoft.com上提交错误报告,并确保提供良好的证据。
000000af  xor         eax,eax 
000000b1  add         eax,4 
            for (int j = 0; j < 100000000; j++) {
000000b4  cmp         eax,5F5E100h 
000000b9  jl          00000000000000B1 
        Console.Write("Sum = {0} ", sum);