Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.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#结构分配效率_C#_Struct - Fatal编程技术网

C#结构分配效率

C#结构分配效率,c#,struct,C#,Struct,在C#中,我有一个结构数组,需要为每个结构赋值。最有效的方法是什么?我可以分配每个字段,为每个字段的数组编制索引: array[i].x = 1; array[i].y = 1; 我可以在堆栈上构造一个新结构并将其复制到数组: array[i] = new Vector2(1, 2); 还有别的办法吗?我可以调用一个方法并通过ref传递结构,但我猜方法调用开销不值得 如果结构大小很重要,所讨论的结构有2-4个float或byte类型的字段 在某些情况下,我需要将相同的值分配给多个数组项,例如

在C#中,我有一个结构数组,需要为每个结构赋值。最有效的方法是什么?我可以分配每个字段,为每个字段的数组编制索引:

array[i].x = 1;
array[i].y = 1;
我可以在堆栈上构造一个新结构并将其复制到数组:

array[i] = new Vector2(1, 2);
还有别的办法吗?我可以调用一个方法并通过ref传递结构,但我猜方法调用开销不值得

如果结构大小很重要,所讨论的结构有2-4个float或byte类型的字段

在某些情况下,我需要将相同的值分配给多个数组项,例如:

Vector2 value = new Vector2(1, 2);
array[i] = value;
array[i + 1] = value;
array[i + 2] = value;
array[i + 3] = value;
这是否改变了哪种方法更有效

我知道这是相当低的水平,但我做了数百万次,我很好奇

编辑:我创建了一个基准:

this.array = new Vector2[100];
Vector2[] array = this.array;
for (int i = 0; i < 1000; i++){
    long startTime, endTime;
    startTime = DateTime.Now.Ticks;
    for (int x = 0; x < 100000000; x++) {
        array[0] = new Vector2(1,2);
        array[1] = new Vector2(3,4);
        array[2] = new Vector2(5,6);
        array[3] = new Vector2(7,8);
        array[4] = new Vector2(9,0);
        array[5] = new Vector2(1,2);
        array[6] = new Vector2(3,4);
        array[7] = new Vector2(5,6);
        array[8] = new Vector2(7,8);
        array[9] = new Vector2(9,0);
    }
    endTime = DateTime.Now.Ticks;
    double ns = ((double)(endTime - startTime)) / ((double)loopCount);
    Debug.Log(ns.ToString("F"));
}
this.array=newvector2[100];
Vector2[]数组=this.array;
对于(int i=0;i<1000;i++){
漫长的开始时间,漫长的结束时间;
startTime=DateTime.Now.Ticks;
对于(int x=0;x<100000000;x++){
数组[0]=新向量2(1,2);
数组[1]=新向量2(3,4);
数组[2]=新向量2(5,6);
数组[3]=新向量2(7,8);
数组[4]=新向量2(9,0);
数组[5]=新向量2(1,2);
数组[6]=新向量2(3,4);
数组[7]=新向量2(5,6);
数组[8]=新向量2(7,8);
数组[9]=新向量2(9,0);
}
endTime=DateTime.Now.Ticks;
double ns=((double)(endTime-startTime))/((double)loopCount);
Debug.Log(ns.ToString(“F”));
}
这报告了约0.77ns,另一个对结构字段进行索引和赋值的版本给出了约0.24ns,FWIW。与结构堆栈分配和复制相比,数组索引似乎便宜。在移动设备上查看性能可能会很有趣


Edit2:Dan Bryant下面的答案是为什么我没有开始编写基准测试,太容易出错。

我对第一种情况(字段分配与构造函数调用)很好奇,所以我制作了一个发布版本并附加了post JIT以查看反汇编。(x64)代码如下所示:

            var array = new Vector2[10];
00000000  mov         ecx,191372h 
00000005  mov         edx,0Ah 
0000000a  call        FFF421C4 
0000000f  mov         edx,eax 

            array[i].x = 1;
00000011  cmp         dword ptr [edx+4],0 
00000015  jbe         0000003E 
00000017  lea         eax,[edx+8] 
0000001a  fld1 
0000001c  fstp        qword ptr [eax] 
            array[i].y = 1;
0000001e  fld1 
00000020  fstp        qword ptr [edx+10h] 

            array[i] = new Vector2(1, 1);
00000023  add         edx,8 
00000026  mov         eax,edx 
00000028  fld1 
0000002a  fld1 
0000002c  fxch        st(1) 
0000002e  fstp        qword ptr [eax] 
00000030  fstp        qword ptr [eax+8] 
值得注意的是,在调试器外部使用发布版本时,“构造函数调用”是内联的,因此,原则上,设置字段和调用构造函数之间应该没有区别。也就是说,抖动在这里做了一些有趣的事情

对于“constructor”版本,它使用了两个浮点堆栈插槽,并将它们同时存储到结构内存(fld1、fld1、fstp、fstp)中。它还有一个fxch(交换),这有点傻,因为两个插槽都包含常量值1,但我认为对于大多数应用程序来说,这并不是一个高优先级的优化目标


对于“单个字段”版本,通过拆分写入(fld1、fstp、fld1、fstp),它只使用FPU堆栈上的一个插槽。我不是x64大师,所以我不知道哪种排序在执行时间方面更有效。不过,任何差异都可能很小,因为主要潜在开销(构造函数方法调用)是内联的。

时间效率?为什么不编写一个测试程序并对其进行分析?@O.R.Mapper,因为有无数种方法可以破坏一个微基准。@JonB我想它可以进行基准测试,尽管我个人不熟悉用C#编写微基准测试。这不仅仅是关于优化,出于学术原因,我对效率感到好奇。这里的一个相关问题是,首先使价值类型可变的影响;这在开发风险方面是有代价的,因为价值类型的微妙性和各种可能错误地改变价值副本的方式,而不是你打算改变的价值。在许多情况下,这种工程(时间和金钱)成本可能超过与小的性能损失相关的同等成本。@DanBryant,这是一个很好的观点。我同意immutable几乎总是更好,在这种情况下,唯一的选择是结构构造函数。在我的特殊情况下,结构来自我无法控制的第三方库。@NateS,请注意,这种行为可能并不代表所有构造函数与字段赋值的情况。优化抖动可以对代码做各种各样的事情,试图从CPU管道中获得各种模糊的好处。不能保证内联,可能会发生各种操作的重新排序。特别是,如果读写的顺序不同于用C#写的顺序,那么只要抖动看到它不应该对逻辑造成影响,就可以得到这样的情况。